diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index a90be5f7f0..7e38c4fa9d 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -296,6 +296,38 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, return header_size + size + integrity_size; } +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) +{ + if (!entity->has_integrity) + return false; + + int header_size = (header >> 24) & 0xff; + + 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; + memcpy(b + header_size, buffer, buffer_size); + + unsigned char integrity[4]; + entity->integrity(entity->integrity_context, integrity, + 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); + + return nmac == mac; +} + /* may be called several times, take care to clean previous settings */ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, int integrity_algorithm, @@ -568,10 +600,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ret->type = type; - ret->recv_pdu = nr_pdcp_entity_recv_pdu; - ret->process_sdu = nr_pdcp_entity_process_sdu; - ret->set_security = nr_pdcp_entity_set_security; - ret->set_time = nr_pdcp_entity_set_time; + ret->recv_pdu = nr_pdcp_entity_recv_pdu; + ret->process_sdu = nr_pdcp_entity_process_sdu; + ret->set_security = nr_pdcp_entity_set_security; + ret->check_integrity = nr_pdcp_entity_check_integrity; + ret->set_time = nr_pdcp_entity_set_time; ret->delete_entity = nr_pdcp_entity_delete; ret->release_entity = nr_pdcp_entity_release; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 94689eac76..058aabc87e 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -104,6 +104,13 @@ typedef struct nr_pdcp_entity_t { int ciphering_algorithm, char *ciphering_key); + /* 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); + void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now); /* callbacks provided to the PDCP module */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index e1d659b3d4..259579d347 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -1062,6 +1062,36 @@ void nr_pdcp_config_set_security(ue_id_t ue_id, nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } +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) +{ + nr_pdcp_ue_t *ue; + nr_pdcp_entity_t *rb; + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + + ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + + rb = nr_pdcp_get_rb(ue, srb_id, true); + + if (rb == NULL) { + LOG_E(PDCP, "no SRB found (ue_id %ld, rb_id %d)\n", ue_id, srb_id); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + return false; + } + + bool ret = rb->check_integrity(rb, msg, msg_size, mac, header, count); + + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + + return ret; +} + bool nr_pdcp_data_req_srb(ue_id_t ue_id, const rb_id_t rb_id, const mui_t muiP, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index be1604dabd..2e87aa9023 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -87,6 +87,14 @@ void nr_pdcp_config_set_security(ue_id_t ue_id, uint8_t *const kRRCint_pP, uint8_t *const kUPenc_pP); +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); + bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_id,