nr pdcp: improve readability of integrity checking
Introduce the structure nr_pdcp_integrity_data_t and adapt code to use it. Note: in nr_pdcp_sdu_t we keep the 'count' variable (which is also present in nr_pdcp_integrity_data_t). They represent the same value, but 'count' in nr_pdcp_integrity_data_t is to be specifically used for integrity while the other one has other uses, so it's better to keep it.
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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 <stdint.h>
|
||||
|
||||
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_ */
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,24 +24,18 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user