Commit a323195a authored by Cedric Roux's avatar Cedric Roux

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.
parent 0f9b3359
......@@ -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),
......
/*
* 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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment