cleanup: reduce number of parameters to pdcp's set_security()

Also adapt callers. In particular nr_pdcp_reestablishment()
This commit is contained in:
Cedric Roux
2024-07-05 12:38:19 +02:00
parent 2db259984f
commit 5467351935
11 changed files with 158 additions and 235 deletions
+2 -1
View File
@@ -298,7 +298,8 @@ void mac_top_init_gNB(ngran_node_t node_type,
* will output the packets at a local interface, which is in line with
* the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */
// setup PDCP, RLC
nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL);
nr_pdcp_entity_security_keys_and_algos_t null_security_parameters = {0};
nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, &null_security_parameters);
nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig);
// free memory
+12 -8
View File
@@ -187,13 +187,15 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
// create PDCP bearers. This will also create SDAP bearers
NR_DRB_ToAddModList_t DRB_configList = {0};
fill_DRB_configList_e1(&DRB_configList, req_pdu);
nr_pdcp_entity_security_keys_and_algos_t security_parameters;
security_parameters.ciphering_algorithm = req->cipheringAlgorithm;
security_parameters.integrity_algorithm = req->integrityProtectionAlgorithm;
memcpy(security_parameters.ciphering_key, req->encryptionKey, NR_K_KEY_SIZE);
memcpy(security_parameters.integrity_key, req->integrityProtectionKey, NR_K_KEY_SIZE);
nr_pdcp_add_drbs(true, // set this to notify PDCP that his not UE
cu_up_ue_id,
&DRB_configList,
(req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm,
(uint8_t *)req->encryptionKey,
(uint8_t *)req->integrityProtectionKey);
&security_parameters);
if (f1inst >= 0) { /* we have F1(-U) */
teid_t dummy_teid = 0xffff; // we will update later with answer from DU
in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU
@@ -255,13 +257,15 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
modified->id = to_modif->id;
if (to_modif->pdcp_config.pDCP_Reestablishment) {
nr_pdcp_entity_security_keys_and_algos_t security_parameters;
security_parameters.ciphering_algorithm = req->cipheringAlgorithm;
security_parameters.integrity_algorithm = req->integrityProtectionAlgorithm;
memcpy(security_parameters.ciphering_key, req->encryptionKey, NR_K_KEY_SIZE);
memcpy(security_parameters.integrity_key, req->integrityProtectionKey, NR_K_KEY_SIZE);
nr_pdcp_reestablishment(req->gNB_cu_up_ue_id,
to_modif->id,
false,
req->integrityProtectionAlgorithm,
(uint8_t *)req->integrityProtectionKey,
req->cipheringAlgorithm,
(uint8_t *)req->encryptionKey);
&security_parameters);
}
if (f1inst < 0) // no F1-U?
+28 -43
View File
@@ -328,38 +328,35 @@ static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity,
}
/* 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,
const uint8_t *integrity_key,
int ciphering_algorithm,
const uint8_t *ciphering_key)
static void nr_pdcp_entity_set_security(struct nr_pdcp_entity_t *entity,
const nr_pdcp_entity_security_keys_and_algos_t *parameters)
{
if (integrity_algorithm != -1)
entity->integrity_algorithm = integrity_algorithm;
if (ciphering_algorithm != -1)
entity->ciphering_algorithm = ciphering_algorithm;
if (integrity_key != NULL)
memcpy(entity->integrity_key, integrity_key, 16);
if (ciphering_key != NULL)
memcpy(entity->ciphering_key, ciphering_key, 16);
if (parameters->integrity_algorithm != -1) {
entity->security_keys_and_algos.integrity_algorithm = parameters->integrity_algorithm;
memcpy(entity->security_keys_and_algos.integrity_key, parameters->integrity_key, NR_K_KEY_SIZE);
}
if (parameters->ciphering_algorithm != -1) {
entity->security_keys_and_algos.ciphering_algorithm = parameters->ciphering_algorithm;
memcpy(entity->security_keys_and_algos.ciphering_key, parameters->ciphering_key, NR_K_KEY_SIZE);
}
if (integrity_algorithm == 0) {
if (parameters->integrity_algorithm == 0) {
entity->has_integrity = 0;
if (entity->free_integrity != NULL)
entity->free_integrity(entity->integrity_context);
entity->free_integrity = NULL;
}
if (integrity_algorithm != 0 && integrity_algorithm != -1) {
if (parameters->integrity_algorithm != 0 && parameters->integrity_algorithm != -1) {
entity->has_integrity = 1;
if (entity->free_integrity != NULL)
entity->free_integrity(entity->integrity_context);
if (integrity_algorithm == 2) {
entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key);
if (parameters->integrity_algorithm == 2) {
entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->security_keys_and_algos.integrity_key);
entity->integrity = nr_pdcp_integrity_nia2_integrity;
entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
} else if (integrity_algorithm == 1) {
entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->integrity_key);
} else if (parameters->integrity_algorithm == 1) {
entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->security_keys_and_algos.integrity_key);
entity->integrity = nr_pdcp_integrity_nia1_integrity;
entity->free_integrity = nr_pdcp_integrity_nia1_free_integrity;
} else {
@@ -368,22 +365,22 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
}
}
if (ciphering_algorithm == 0) {
if (parameters->ciphering_algorithm == 0) {
entity->has_ciphering = 0;
if (entity->free_security != NULL)
entity->free_security(entity->security_context);
entity->free_security = NULL;
}
if (ciphering_algorithm != 0 && ciphering_algorithm != -1) {
if (ciphering_algorithm != 2) {
if (parameters->ciphering_algorithm != 0 && parameters->ciphering_algorithm != -1) {
if (parameters->ciphering_algorithm != 2) {
LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
exit(1);
}
entity->has_ciphering = 1;
if (entity->free_security != NULL)
entity->free_security(entity->security_context);
entity->security_context = nr_pdcp_security_nea2_init(entity->ciphering_key);
entity->security_context = nr_pdcp_security_nea2_init(entity->security_keys_and_algos.ciphering_key);
entity->cipher = nr_pdcp_security_nea2_cipher;
entity->free_security = nr_pdcp_security_nea2_free_security;
}
@@ -516,10 +513,7 @@ static void free_rx_list(nr_pdcp_entity_t *entity)
* @todo deal with ciphering/integrity algos and keys for transmitting/receiving entity procedures
*/
static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity,
int integrity_algorithm,
const uint8_t *integrity_key,
int ciphering_algorithm,
const uint8_t *ciphering_key)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
/* transmitting entity procedures */
/* do nothing */
@@ -528,17 +522,14 @@ static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity,
/* do nothing */
/* ciphering and integrity: common for both tx and rx entities */
entity->set_security(entity, integrity_algorithm, integrity_key, ciphering_algorithm, ciphering_key);
entity->set_security(entity, security_parameters);
/* Flag PDCP entity as re-established */
entity->entity_suspended = false;
}
static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity,
int integrity_algorithm,
const uint8_t *integrity_key,
int ciphering_algorithm,
const uint8_t *ciphering_key)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
/* transmitting entity procedures */
entity->tx_next = 0;
@@ -554,17 +545,14 @@ static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity,
entity->rx_deliv = 0;
/* ciphering and integrity: common for both tx and rx entities */
entity->set_security(entity, integrity_algorithm, integrity_key, ciphering_algorithm, ciphering_key);
entity->set_security(entity, security_parameters);
/* Flag PDCP entity as re-established */
entity->entity_suspended = false;
}
static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity,
int integrity_algorithm,
const uint8_t *integrity_key,
int ciphering_algorithm,
const uint8_t *ciphering_key)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
/* transmitting entity procedures */
entity->tx_next = 0;
@@ -578,7 +566,7 @@ static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity,
entity->rx_deliv = 0;
/* ciphering and integrity: common for both tx and rx entities */
entity->set_security(entity, integrity_algorithm, integrity_key, ciphering_algorithm, ciphering_key);
entity->set_security(entity, security_parameters);
/* Flag PDCP entity as re-established */
entity->entity_suspended = false;
@@ -623,10 +611,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
int sn_size,
int t_reordering,
int discard_timer,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
nr_pdcp_entity_t *ret;
@@ -680,7 +665,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
ret->is_gnb = is_gnb;
nr_pdcp_entity_set_security(ret, integrity_algorithm, integrity_key, ciphering_algorithm, ciphering_key);
nr_pdcp_entity_set_security(ret, security_parameters);
return ret;
}
+13 -20
View File
@@ -48,6 +48,13 @@ typedef enum {
NR_PDCP_SRB
} nr_pdcp_entity_type_t;
typedef struct {
int integrity_algorithm;
int ciphering_algorithm;
uint8_t integrity_key[NR_K_KEY_SIZE];
uint8_t ciphering_key[NR_K_KEY_SIZE];
} nr_pdcp_entity_security_keys_and_algos_t;
typedef struct {
//nr_pdcp_entity_type_t mode;
/* PDU stats */
@@ -92,22 +99,14 @@ typedef struct nr_pdcp_entity_t {
void (*release_entity)(struct nr_pdcp_entity_t *entity);
void (*suspend_entity)(struct nr_pdcp_entity_t *entity);
void (*reestablish_entity)(struct nr_pdcp_entity_t *entity,
int integrity_algorithm,
const uint8_t *integrity_key,
int ciphering_algorithm,
const uint8_t *ciphering_key);
const nr_pdcp_entity_security_keys_and_algos_t *parameters);
void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out);
/* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
* to keep the current algorithm
* pass NULL to integrity_key / ciphering_key
* to keep the current key
/* set_security: pass -1 to parameters->integrity_algorithm / parameters->ciphering_algorithm
* to keep the corresponding current algorithm and key
*/
void (*set_security)(struct nr_pdcp_entity_t *entity,
int integrity_algorithm,
const uint8_t *integrity_key,
int ciphering_algorithm,
const uint8_t *ciphering_key);
const nr_pdcp_entity_security_keys_and_algos_t *parameters);
/* check_integrity is used by RRC */
bool (*check_integrity)(struct nr_pdcp_entity_t *entity,
@@ -152,10 +151,7 @@ typedef struct nr_pdcp_entity_t {
/* security */
int has_ciphering;
int has_integrity;
int ciphering_algorithm;
int integrity_algorithm;
unsigned char ciphering_key[16];
unsigned char integrity_key[16];
nr_pdcp_entity_security_keys_and_algos_t security_keys_and_algos;
stream_security_context_t *security_context;
void (*cipher)(stream_security_context_t *security_context,
unsigned char *buffer, int length,
@@ -200,10 +196,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
int sn_size,
int t_reordering,
int discard_timer,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
/* Get maximum PDCP PDU size */
int nr_max_pdcp_pdu_size(sdu_size_t sdu_size);
+18 -42
View File
@@ -798,10 +798,7 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id,
void add_srb(int is_gnb,
ue_id_t UEid,
struct NR_SRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
nr_pdcp_entity_t *pdcp_srb;
nr_pdcp_ue_t *ue;
@@ -829,10 +826,7 @@ void add_srb(int is_gnb,
SHORT_SN_SIZE,
t_Reordering,
-1,
ciphering_algorithm,
integrity_algorithm,
ciphering_key,
integrity_key);
security_parameters);
nr_pdcp_ue_add_srb_pdcp_entity(ue, srb_id, pdcp_srb);
LOG_D(PDCP, "added srb %d to UE ID %ld\n", srb_id, UEid);
@@ -843,10 +837,7 @@ void add_srb(int is_gnb,
void add_drb(int is_gnb,
ue_id_t UEid,
struct NR_DRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue;
@@ -910,6 +901,10 @@ void add_drb(int is_gnb,
exit(1);
}
/* get actual ciphering and integrity algorithm based on pdcp_Config */
nr_pdcp_entity_security_keys_and_algos_t actual_security_parameters = *security_parameters;
actual_security_parameters.ciphering_algorithm = has_ciphering ? security_parameters->ciphering_algorithm : 0;
actual_security_parameters.integrity_algorithm = has_integrity ? security_parameters->integrity_algorithm : 0;
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid);
@@ -922,10 +917,7 @@ void add_drb(int is_gnb,
deliver_pdu_drb_gnb : deliver_pdu_drb_ue,
ue,
sn_size_dl, t_reordering, discard_timer,
has_ciphering ? ciphering_algorithm : 0,
has_integrity ? integrity_algorithm : 0,
has_ciphering ? ciphering_key : NULL,
has_integrity ? integrity_key : NULL);
&actual_security_parameters);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
LOG_I(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid);
@@ -946,13 +938,11 @@ void add_drb(int is_gnb,
void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
ue_id_t UEid,
NR_SRB_ToAddModList_t *const srb2add_list,
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
if (srb2add_list != NULL) {
for (int i = 0; i < srb2add_list->list.count; i++) {
add_srb(enb_flag, UEid, srb2add_list->list.array[i], security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kRRCenc, kRRCint);
add_srb(enb_flag, UEid, srb2add_list->list.array[i], security_parameters);
}
} else
LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n");
@@ -961,19 +951,14 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t UEid,
NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP,
uint8_t *const kUPenc,
uint8_t *const kUPint)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
if (drb2add_list != NULL) {
for (int i = 0; i < drb2add_list->list.count; i++) {
add_drb(enb_flag,
UEid,
drb2add_list->list.array[i],
security_modeP & 0x0f,
(security_modeP >> 4) & 0x0f,
kUPenc,
kUPint);
security_parameters);
}
} else
LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n");
@@ -1026,16 +1011,12 @@ void pdcp_config_set_security(const protocol_ctxt_t *const ctxt_pP,
}
void nr_pdcp_config_set_security(ue_id_t ue_id,
const rb_id_t rb_id,
const bool is_srb,
const uint8_t security_mode,
const uint8_t *kenc,
const uint8_t *kint)
rb_id_t rb_id,
bool is_srb,
const nr_pdcp_entity_security_keys_and_algos_t *parameters)
{
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
int integrity_algorithm;
int ciphering_algorithm;
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
@@ -1049,9 +1030,7 @@ void nr_pdcp_config_set_security(ue_id_t ue_id,
return;
}
integrity_algorithm = (security_mode >> 4) & 0xf;
ciphering_algorithm = security_mode & 0x0f;
rb->set_security(rb, integrity_algorithm, kint, ciphering_algorithm, kenc);
rb->set_security(rb, parameters);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
@@ -1240,10 +1219,7 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id)
void nr_pdcp_reestablishment(ue_id_t ue_id,
int rb_id,
bool srb_flag,
int ciphering_algorithm,
const uint8_t *ciphering_key,
int integrity_algorithm,
const uint8_t *integrity_key)
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
@@ -1254,7 +1230,7 @@ void nr_pdcp_reestablishment(ue_id_t ue_id,
if (rb != NULL) {
LOG_D(PDCP, "UE %4.4lx re-establishment of %sRB %d\n", ue_id, srb_flag ? "S" : "D", rb_id);
rb->reestablish_entity(rb, ciphering_algorithm, ciphering_key, integrity_algorithm, integrity_key);
rb->reestablish_entity(rb, security_parameters);
LOG_I(PDCP, "%s %d re-established\n", srb_flag ? "SRB" : "DRB" , rb_id);
} else {
LOG_W(PDCP, "UE %4.4lx cannot re-establish %sRB %d, RB not found\n", ue_id, srb_flag ? "S" : "D", rb_id);
+12 -21
View File
@@ -49,26 +49,23 @@ bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t UEid,
NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP,
uint8_t *const kUPenc,
uint8_t *const kUPint);
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
ue_id_t UEid,
NR_SRB_ToAddModList_t *const srb2add_list,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void add_drb(int is_gnb,
ue_id_t UEid,
struct NR_DRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void nr_pdcp_remove_UE(ue_id_t ue_id);
void nr_pdcp_reestablishment(ue_id_t ue_id,
int rb_id,
bool srb_flag,
int ciphering_algorithm,
const uint8_t *ciphering_key,
int integrity_algorithm,
const uint8_t *integrity_key);
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id);
void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id);
@@ -77,21 +74,15 @@ void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_c
void nr_pdcp_release_srb(ue_id_t ue_id, int srb_id);
void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id);
void add_srb(int is_gnb,
ue_id_t UEid,
struct NR_SRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void nr_pdcp_config_set_security(ue_id_t ue_id,
const rb_id_t rb_id,
const bool is_srb,
const uint8_t security_mode,
const uint8_t *kenc,
const uint8_t *kint);
rb_id_t rb_id,
bool is_srb,
const nr_pdcp_entity_security_keys_and_algos_t *parameters);
bool nr_pdcp_check_integrity_srb(ue_id_t ue_id,
int srb_id,