Commit 884127c3 authored by Cedric Roux's avatar Cedric Roux

nr pdcp: add an API function to check integrity

parent ec917d4d
......@@ -268,6 +268,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,
......@@ -526,10 +558,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;
......
......@@ -92,6 +92,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 */
......
......@@ -1050,6 +1050,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,
......
......@@ -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,
......
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