Commit 8b9891f2 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/bugfix-security-reestablishment-gnb' into integration_2024_w27

parents 7f63a702 0480b69c
...@@ -298,7 +298,8 @@ void mac_top_init_gNB(ngran_node_t node_type, ...@@ -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 * will output the packets at a local interface, which is in line with
* the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */ * the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */
// setup PDCP, RLC // 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); nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig);
// free memory // free memory
......
...@@ -187,13 +187,15 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) ...@@ -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 // create PDCP bearers. This will also create SDAP bearers
NR_DRB_ToAddModList_t DRB_configList = {0}; NR_DRB_ToAddModList_t DRB_configList = {0};
fill_DRB_configList_e1(&DRB_configList, req_pdu); 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 nr_pdcp_add_drbs(true, // set this to notify PDCP that his not UE
cu_up_ue_id, cu_up_ue_id,
&DRB_configList, &DRB_configList,
(req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm, &security_parameters);
(uint8_t *)req->encryptionKey,
(uint8_t *)req->integrityProtectionKey);
if (f1inst >= 0) { /* we have F1(-U) */ if (f1inst >= 0) { /* we have F1(-U) */
teid_t dummy_teid = 0xffff; // we will update later with answer from DU 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 in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU
...@@ -255,7 +257,15 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req) ...@@ -255,7 +257,15 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
modified->id = to_modif->id; modified->id = to_modif->id;
if (to_modif->pdcp_config.pDCP_Reestablishment) { if (to_modif->pdcp_config.pDCP_Reestablishment) {
nr_pdcp_reestablishment(req->gNB_cu_up_ue_id, to_modif->id, false); 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,
&security_parameters);
} }
if (f1inst < 0) // no F1-U? if (f1inst < 0) // no F1-U?
......
...@@ -328,38 +328,35 @@ static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity, ...@@ -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 */ /* may be called several times, take care to clean previous settings */
static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, static void nr_pdcp_entity_set_security(struct nr_pdcp_entity_t *entity,
int integrity_algorithm, const nr_pdcp_entity_security_keys_and_algos_t *parameters)
char *integrity_key,
int ciphering_algorithm,
char *ciphering_key)
{ {
if (integrity_algorithm != -1) if (parameters->integrity_algorithm != -1) {
entity->integrity_algorithm = integrity_algorithm; entity->security_keys_and_algos.integrity_algorithm = parameters->integrity_algorithm;
if (ciphering_algorithm != -1) memcpy(entity->security_keys_and_algos.integrity_key, parameters->integrity_key, NR_K_KEY_SIZE);
entity->ciphering_algorithm = ciphering_algorithm; }
if (integrity_key != NULL) if (parameters->ciphering_algorithm != -1) {
memcpy(entity->integrity_key, integrity_key, 16); entity->security_keys_and_algos.ciphering_algorithm = parameters->ciphering_algorithm;
if (ciphering_key != NULL) memcpy(entity->security_keys_and_algos.ciphering_key, parameters->ciphering_key, NR_K_KEY_SIZE);
memcpy(entity->ciphering_key, ciphering_key, 16); }
if (integrity_algorithm == 0) { if (parameters->integrity_algorithm == 0) {
entity->has_integrity = 0; entity->has_integrity = 0;
if (entity->free_integrity != NULL) if (entity->free_integrity != NULL)
entity->free_integrity(entity->integrity_context); entity->free_integrity(entity->integrity_context);
entity->free_integrity = NULL; entity->free_integrity = NULL;
} }
if (integrity_algorithm != 0 && integrity_algorithm != -1) { if (parameters->integrity_algorithm != 0 && parameters->integrity_algorithm != -1) {
entity->has_integrity = 1; entity->has_integrity = 1;
if (entity->free_integrity != NULL) if (entity->free_integrity != NULL)
entity->free_integrity(entity->integrity_context); entity->free_integrity(entity->integrity_context);
if (integrity_algorithm == 2) { if (parameters->integrity_algorithm == 2) {
entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key); entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->security_keys_and_algos.integrity_key);
entity->integrity = nr_pdcp_integrity_nia2_integrity; entity->integrity = nr_pdcp_integrity_nia2_integrity;
entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity; entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
} else if (integrity_algorithm == 1) { } else if (parameters->integrity_algorithm == 1) {
entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->integrity_key); entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->security_keys_and_algos.integrity_key);
entity->integrity = nr_pdcp_integrity_nia1_integrity; entity->integrity = nr_pdcp_integrity_nia1_integrity;
entity->free_integrity = nr_pdcp_integrity_nia1_free_integrity; entity->free_integrity = nr_pdcp_integrity_nia1_free_integrity;
} else { } else {
...@@ -368,22 +365,22 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, ...@@ -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; entity->has_ciphering = 0;
if (entity->free_security != NULL) if (entity->free_security != NULL)
entity->free_security(entity->security_context); entity->free_security(entity->security_context);
entity->free_security = NULL; entity->free_security = NULL;
} }
if (ciphering_algorithm != 0 && ciphering_algorithm != -1) { if (parameters->ciphering_algorithm != 0 && parameters->ciphering_algorithm != -1) {
if (ciphering_algorithm != 2) { if (parameters->ciphering_algorithm != 2) {
LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n"); LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
exit(1); exit(1);
} }
entity->has_ciphering = 1; entity->has_ciphering = 1;
if (entity->free_security != NULL) if (entity->free_security != NULL)
entity->free_security(entity->security_context); 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->cipher = nr_pdcp_security_nea2_cipher;
entity->free_security = nr_pdcp_security_nea2_free_security; entity->free_security = nr_pdcp_security_nea2_free_security;
} }
...@@ -515,23 +512,27 @@ static void free_rx_list(nr_pdcp_entity_t *entity) ...@@ -515,23 +512,27 @@ static void free_rx_list(nr_pdcp_entity_t *entity)
* @brief PDCP entity re-establishment according to 5.1.2 of 3GPP TS 38.323 * @brief PDCP entity re-establishment according to 5.1.2 of 3GPP TS 38.323
* @todo deal with ciphering/integrity algos and keys for transmitting/receiving entity procedures * @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) static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{ {
/* transmitting entity procedures */ /* transmitting entity procedures */
/* todo: deal with ciphering/integrity algos and keys */ /* do nothing */
/* receiving entity procedures */ /* receiving entity procedures */
/* todo: deal with ciphering/integrity algos and keys */ /* do nothing */
/* ciphering and integrity: common for both tx and rx entities */
entity->set_security(entity, security_parameters);
/* Flag PDCP entity as re-established */ /* Flag PDCP entity as re-established */
entity->entity_suspended = false; entity->entity_suspended = false;
} }
static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{ {
/* transmitting entity procedures */ /* transmitting entity procedures */
entity->tx_next = 0; entity->tx_next = 0;
/* todo: deal with ciphering/integrity algos and keys */
/* receiving entity procedures */ /* receiving entity procedures */
/* deliver all SDUs if t_reordering is running */ /* deliver all SDUs if t_reordering is running */
...@@ -542,17 +543,19 @@ static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) ...@@ -542,17 +543,19 @@ static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity)
/* set rx_next and rx_deliv to the initial value */ /* set rx_next and rx_deliv to the initial value */
entity->rx_next = 0; entity->rx_next = 0;
entity->rx_deliv = 0; entity->rx_deliv = 0;
/* todo: deal with ciphering/integrity algos and keys */
/* ciphering and integrity: common for both tx and rx entities */
entity->set_security(entity, security_parameters);
/* Flag PDCP entity as re-established */ /* Flag PDCP entity as re-established */
entity->entity_suspended = false; entity->entity_suspended = false;
} }
static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{ {
/* transmitting entity procedures */ /* transmitting entity procedures */
entity->tx_next = 0; entity->tx_next = 0;
/* todo: deal with ciphering/integrity algos and keys */
/* receiving entity procedures */ /* receiving entity procedures */
free_rx_list(entity); free_rx_list(entity);
...@@ -561,7 +564,9 @@ static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) ...@@ -561,7 +564,9 @@ static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity)
/* set rx_next and rx_deliv to the initial value */ /* set rx_next and rx_deliv to the initial value */
entity->rx_next = 0; entity->rx_next = 0;
entity->rx_deliv = 0; entity->rx_deliv = 0;
/* todo: deal with ciphering/integrity algos and keys */
/* ciphering and integrity: common for both tx and rx entities */
entity->set_security(entity, security_parameters);
/* Flag PDCP entity as re-established */ /* Flag PDCP entity as re-established */
entity->entity_suspended = false; entity->entity_suspended = false;
...@@ -606,10 +611,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ...@@ -606,10 +611,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
int sn_size, int sn_size,
int t_reordering, int t_reordering,
int discard_timer, int discard_timer,
int ciphering_algorithm, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{ {
nr_pdcp_entity_t *ret; nr_pdcp_entity_t *ret;
...@@ -663,9 +665,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ...@@ -663,9 +665,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
ret->is_gnb = is_gnb; ret->is_gnb = is_gnb;
nr_pdcp_entity_set_security(ret, nr_pdcp_entity_set_security(ret, security_parameters);
integrity_algorithm, (char *)integrity_key,
ciphering_algorithm, (char *)ciphering_key);
return ret; return ret;
} }
...@@ -48,6 +48,13 @@ typedef enum { ...@@ -48,6 +48,13 @@ typedef enum {
NR_PDCP_SRB NR_PDCP_SRB
} nr_pdcp_entity_type_t; } 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 { typedef struct {
//nr_pdcp_entity_type_t mode; //nr_pdcp_entity_type_t mode;
/* PDU stats */ /* PDU stats */
...@@ -91,19 +98,15 @@ typedef struct nr_pdcp_entity_t { ...@@ -91,19 +98,15 @@ typedef struct nr_pdcp_entity_t {
void (*delete_entity)(struct nr_pdcp_entity_t *entity); void (*delete_entity)(struct nr_pdcp_entity_t *entity);
void (*release_entity)(struct nr_pdcp_entity_t *entity); void (*release_entity)(struct nr_pdcp_entity_t *entity);
void (*suspend_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); void (*reestablish_entity)(struct nr_pdcp_entity_t *entity,
const nr_pdcp_entity_security_keys_and_algos_t *parameters);
void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out); void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out);
/* set_security: pass -1 to integrity_algorithm / ciphering_algorithm /* set_security: pass -1 to parameters->integrity_algorithm / parameters->ciphering_algorithm
* to keep the current algorithm * to keep the corresponding current algorithm and key
* pass NULL to integrity_key / ciphering_key
* to keep the current key
*/ */
void (*set_security)(struct nr_pdcp_entity_t *entity, void (*set_security)(struct nr_pdcp_entity_t *entity,
int integrity_algorithm, const nr_pdcp_entity_security_keys_and_algos_t *parameters);
char *integrity_key,
int ciphering_algorithm,
char *ciphering_key);
/* check_integrity is used by RRC */ /* check_integrity is used by RRC */
bool (*check_integrity)(struct nr_pdcp_entity_t *entity, bool (*check_integrity)(struct nr_pdcp_entity_t *entity,
...@@ -148,10 +151,7 @@ typedef struct nr_pdcp_entity_t { ...@@ -148,10 +151,7 @@ typedef struct nr_pdcp_entity_t {
/* security */ /* security */
int has_ciphering; int has_ciphering;
int has_integrity; int has_integrity;
int ciphering_algorithm; nr_pdcp_entity_security_keys_and_algos_t security_keys_and_algos;
int integrity_algorithm;
unsigned char ciphering_key[16];
unsigned char integrity_key[16];
stream_security_context_t *security_context; stream_security_context_t *security_context;
void (*cipher)(stream_security_context_t *security_context, void (*cipher)(stream_security_context_t *security_context,
unsigned char *buffer, int length, unsigned char *buffer, int length,
...@@ -196,10 +196,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ...@@ -196,10 +196,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
int sn_size, int sn_size,
int t_reordering, int t_reordering,
int discard_timer, int discard_timer,
int ciphering_algorithm, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
/* Get maximum PDCP PDU size */ /* Get maximum PDCP PDU size */
int nr_max_pdcp_pdu_size(sdu_size_t sdu_size); int nr_max_pdcp_pdu_size(sdu_size_t sdu_size);
......
...@@ -798,10 +798,7 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, ...@@ -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, void add_srb(int is_gnb,
ue_id_t UEid, ue_id_t UEid,
struct NR_SRB_ToAddMod *s, struct NR_SRB_ToAddMod *s,
int ciphering_algorithm, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{ {
nr_pdcp_entity_t *pdcp_srb; nr_pdcp_entity_t *pdcp_srb;
nr_pdcp_ue_t *ue; nr_pdcp_ue_t *ue;
...@@ -829,10 +826,7 @@ void add_srb(int is_gnb, ...@@ -829,10 +826,7 @@ void add_srb(int is_gnb,
SHORT_SN_SIZE, SHORT_SN_SIZE,
t_Reordering, t_Reordering,
-1, -1,
ciphering_algorithm, security_parameters);
integrity_algorithm,
ciphering_key,
integrity_key);
nr_pdcp_ue_add_srb_pdcp_entity(ue, srb_id, pdcp_srb); 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); LOG_D(PDCP, "added srb %d to UE ID %ld\n", srb_id, UEid);
...@@ -843,10 +837,7 @@ void add_srb(int is_gnb, ...@@ -843,10 +837,7 @@ void add_srb(int is_gnb,
void add_drb(int is_gnb, void add_drb(int is_gnb,
ue_id_t UEid, ue_id_t UEid,
struct NR_DRB_ToAddMod *s, struct NR_DRB_ToAddMod *s,
int ciphering_algorithm, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{ {
nr_pdcp_entity_t *pdcp_drb; nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue; nr_pdcp_ue_t *ue;
...@@ -910,6 +901,10 @@ void add_drb(int is_gnb, ...@@ -910,6 +901,10 @@ void add_drb(int is_gnb,
exit(1); 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); nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid);
...@@ -922,10 +917,7 @@ void add_drb(int is_gnb, ...@@ -922,10 +917,7 @@ void add_drb(int is_gnb,
deliver_pdu_drb_gnb : deliver_pdu_drb_ue, deliver_pdu_drb_gnb : deliver_pdu_drb_ue,
ue, ue,
sn_size_dl, t_reordering, discard_timer, sn_size_dl, t_reordering, discard_timer,
has_ciphering ? ciphering_algorithm : 0, &actual_security_parameters);
has_integrity ? integrity_algorithm : 0,
has_ciphering ? ciphering_key : NULL,
has_integrity ? integrity_key : NULL);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); 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); LOG_I(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid);
...@@ -946,13 +938,11 @@ void add_drb(int is_gnb, ...@@ -946,13 +938,11 @@ void add_drb(int is_gnb,
void nr_pdcp_add_srbs(eNB_flag_t enb_flag, void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
ue_id_t UEid, ue_id_t UEid,
NR_SRB_ToAddModList_t *const srb2add_list, NR_SRB_ToAddModList_t *const srb2add_list,
const uint8_t security_modeP, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
uint8_t *const kRRCenc,
uint8_t *const kRRCint)
{ {
if (srb2add_list != NULL) { if (srb2add_list != NULL) {
for (int i = 0; i < srb2add_list->list.count; i++) { 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 } else
LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n"); 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, ...@@ -961,19 +951,14 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
void nr_pdcp_add_drbs(eNB_flag_t enb_flag, void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t UEid, ue_id_t UEid,
NR_DRB_ToAddModList_t *const drb2add_list, NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
uint8_t *const kUPenc,
uint8_t *const kUPint)
{ {
if (drb2add_list != NULL) { if (drb2add_list != NULL) {
for (int i = 0; i < drb2add_list->list.count; i++) { for (int i = 0; i < drb2add_list->list.count; i++) {
add_drb(enb_flag, add_drb(enb_flag,
UEid, UEid,
drb2add_list->list.array[i], drb2add_list->list.array[i],
security_modeP & 0x0f, security_parameters);
(security_modeP >> 4) & 0x0f,
kUPenc,
kUPint);
} }
} else } else
LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n");
...@@ -1026,35 +1011,26 @@ void pdcp_config_set_security(const protocol_ctxt_t *const ctxt_pP, ...@@ -1026,35 +1011,26 @@ void pdcp_config_set_security(const protocol_ctxt_t *const ctxt_pP,
} }
void nr_pdcp_config_set_security(ue_id_t ue_id, void nr_pdcp_config_set_security(ue_id_t ue_id,
const rb_id_t rb_id, rb_id_t rb_id,
const uint8_t security_modeP, bool is_srb,
uint8_t *const kRRCenc_pP, const nr_pdcp_entity_security_keys_and_algos_t *parameters)
uint8_t *const kRRCint_pP,
uint8_t *const kUPenc_pP)
{ {
nr_pdcp_ue_t *ue; nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb; nr_pdcp_entity_t *rb;
int integrity_algorithm;
int ciphering_algorithm;
nr_pdcp_manager_lock(nr_pdcp_ue_manager); nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
/* TODO: proper handling of DRBs, for the moment only SRBs are handled */ rb = nr_pdcp_get_rb(ue, rb_id, is_srb);
rb = nr_pdcp_get_rb(ue, rb_id, true);
if (rb == NULL) { if (rb == NULL) {
nr_pdcp_manager_unlock(nr_pdcp_ue_manager); nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
LOG_E(PDCP, "no SRB found (ue_id %ld, rb_id %ld)\n", ue_id, rb_id); LOG_E(PDCP, "no %s found (ue_id %ld, rb_id %ld)\n", is_srb ? "SRB" : "DRB", ue_id, rb_id);
return; return;
} }
integrity_algorithm = (security_modeP>>4) & 0xf; rb->set_security(rb, parameters);
ciphering_algorithm = security_modeP & 0x0f;
rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
ciphering_algorithm, (char *)kRRCenc_pP);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager); nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
} }
...@@ -1240,7 +1216,10 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id) ...@@ -1240,7 +1216,10 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id)
nr_pdcp_manager_unlock(nr_pdcp_ue_manager); nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
} }
void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag) void nr_pdcp_reestablishment(ue_id_t ue_id,
int rb_id,
bool srb_flag,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{ {
nr_pdcp_ue_t *ue; nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb; nr_pdcp_entity_t *rb;
...@@ -1251,7 +1230,7 @@ void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag) ...@@ -1251,7 +1230,7 @@ void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag)
if (rb != NULL) { if (rb != NULL) {
LOG_D(PDCP, "UE %4.4lx re-establishment of %sRB %d\n", ue_id, srb_flag ? "S" : "D", rb_id); LOG_D(PDCP, "UE %4.4lx re-establishment of %sRB %d\n", ue_id, srb_flag ? "S" : "D", rb_id);
rb->reestablish_entity(rb); rb->reestablish_entity(rb, security_parameters);
LOG_I(PDCP, "%s %d re-established\n", srb_flag ? "SRB" : "DRB" , rb_id); LOG_I(PDCP, "%s %d re-established\n", srb_flag ? "SRB" : "DRB" , rb_id);
} else { } else {
LOG_W(PDCP, "UE %4.4lx cannot re-establish %sRB %d, RB not found\n", ue_id, srb_flag ? "S" : "D", rb_id); LOG_W(PDCP, "UE %4.4lx cannot re-establish %sRB %d, RB not found\n", ue_id, srb_flag ? "S" : "D", rb_id);
......
...@@ -49,20 +49,23 @@ bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, ...@@ -49,20 +49,23 @@ bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
void nr_pdcp_add_drbs(eNB_flag_t enb_flag, void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t UEid, ue_id_t UEid,
NR_DRB_ToAddModList_t *const drb2add_list, NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
uint8_t *const kUPenc,
uint8_t *const kUPint); 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, void add_drb(int is_gnb,
ue_id_t UEid, ue_id_t UEid,
struct NR_DRB_ToAddMod *s, struct NR_DRB_ToAddMod *s,
int ciphering_algorithm, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
void nr_pdcp_remove_UE(ue_id_t ue_id); 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); void nr_pdcp_reestablishment(ue_id_t ue_id,
int rb_id,
bool srb_flag,
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_srb(ue_id_t ue_id, int srb_id);
void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id); void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id);
...@@ -71,21 +74,15 @@ void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_c ...@@ -71,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_srb(ue_id_t ue_id, int srb_id);
void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id); void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id);
void add_srb(int is_gnb, void add_srb(int is_gnb,
ue_id_t UEid, ue_id_t UEid,
struct NR_SRB_ToAddMod *s, struct NR_SRB_ToAddMod *s,
int ciphering_algorithm, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
void nr_pdcp_config_set_security(ue_id_t ue_id, void nr_pdcp_config_set_security(ue_id_t ue_id,
const rb_id_t rb_id, rb_id_t rb_id,
const uint8_t security_modeP, bool is_srb,
uint8_t *const kRRCenc_pP, const nr_pdcp_entity_security_keys_and_algos_t *parameters);
uint8_t *const kRRCint_pP,
uint8_t *const kUPenc_pP);
bool nr_pdcp_check_integrity_srb(ue_id_t ue_id, bool nr_pdcp_check_integrity_srb(ue_id_t ue_id,
int srb_id, int srb_id,
......
...@@ -145,20 +145,6 @@ void ue_cxt_mod_direct(MessageDef *msg, ...@@ -145,20 +145,6 @@ void ue_cxt_mod_direct(MessageDef *msg,
void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p,
e1ap_bearer_setup_resp_t *e1ap_resp); e1ap_bearer_setup_resp_t *e1ap_resp);
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 kUPint);
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t rntiMaybeUEid,
NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP,
uint8_t *const kUPenc,
uint8_t *const kUPint);
void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink); void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink);
int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint32_t tmsi, uint8_t paging_drx); int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint32_t tmsi, uint8_t paging_drx);
......
...@@ -389,19 +389,19 @@ static void activate_srb(gNB_RRC_UE_t *UE, int srb_id) ...@@ -389,19 +389,19 @@ static void activate_srb(gNB_RRC_UE_t *UE, int srb_id)
srb->srb_Identity = srb_id; srb->srb_Identity = srb_id;
if (srb_id == 1) { if (srb_id == 1) {
nr_pdcp_add_srbs(true, UE->rrc_ue_id, list, 0, NULL, NULL); nr_pdcp_entity_security_keys_and_algos_t null_security_parameters = {0};
nr_pdcp_add_srbs(true, UE->rrc_ue_id, list, &null_security_parameters);
} else { } else {
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; nr_pdcp_entity_security_keys_and_algos_t security_parameters;
uint8_t kRRCint[NR_K_KEY_SIZE] = {0}; security_parameters.ciphering_algorithm = UE->ciphering_algorithm;
nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); security_parameters.integrity_algorithm = UE->integrity_algorithm;
nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, security_parameters.ciphering_key);
nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, security_parameters.integrity_key);
nr_pdcp_add_srbs(true, nr_pdcp_add_srbs(true,
UE->rrc_ue_id, UE->rrc_ue_id,
list, list,
(UE->integrity_algorithm << 4) | UE->ciphering_algorithm, &security_parameters);
kRRCenc,
kRRCint);
} }
freeSRBlist(list); freeSRBlist(list);
} }
...@@ -850,6 +850,12 @@ static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p) ...@@ -850,6 +850,12 @@ static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
/* increase DRB to modify counter */ /* increase DRB to modify counter */
pdu_e1->numDRB2Modify += 1; pdu_e1->numDRB2Modify += 1;
} }
req.cipheringAlgorithm = rrc->security.do_drb_ciphering ? ue_p->ciphering_algorithm : 0;
req.integrityProtectionAlgorithm = rrc->security.do_drb_integrity ? ue_p->integrity_algorithm : 0;
nr_derive_key(UP_ENC_ALG, req.cipheringAlgorithm, ue_p->kgnb, (uint8_t *)req.encryptionKey);
nr_derive_key(UP_INT_ALG, req.integrityProtectionAlgorithm, ue_p->kgnb, (uint8_t *)req.integrityProtectionKey);
/* Send E1 Bearer Context Modification Request (3GPP TS 38.463) */ /* Send E1 Bearer Context Modification Request (3GPP TS 38.463) */
sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, ue_p); sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, ue_p);
rrc->cucp_cuup.bearer_context_mod(assoc_id, &req); rrc->cucp_cuup.bearer_context_mod(assoc_id, &req);
...@@ -866,7 +872,6 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context ...@@ -866,7 +872,6 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
{ {
module_id_t module_id = 0; module_id_t module_id = 0;
gNB_RRC_INST *rrc = RC.nrrrc[module_id]; gNB_RRC_INST *rrc = RC.nrrrc[module_id];
int enable_ciphering = 0;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
uint8_t buffer[RRC_BUF_SIZE] = {0}; uint8_t buffer[RRC_BUF_SIZE] = {0};
uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id);
...@@ -878,30 +883,33 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context ...@@ -878,30 +883,33 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size); LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size);
/* Ciphering and Integrity according to TS 33.501 */ /* Ciphering and Integrity according to TS 33.501 */
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; nr_pdcp_entity_security_keys_and_algos_t security_parameters;
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
uint8_t kUPenc[NR_K_KEY_SIZE] = {0};
/* Derive the keys from kgnb */ /* Derive the keys from kgnb */
if (ue_p->Srb[1].Active) nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, security_parameters.ciphering_key);
nr_derive_key(UP_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kUPenc); nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, security_parameters.integrity_key);
nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint);
LOG_I(NR_RRC, LOG_I(NR_RRC,
"Set PDCP security UE %d RNTI %04x nca %ld nia %d in RRCReestablishment\n", "Set PDCP security UE %d RNTI %04x nea %ld nia %d in RRCReestablishment\n",
ue_p->rrc_ue_id, ue_p->rrc_ue_id,
ue_p->rnti, ue_p->rnti,
ue_p->ciphering_algorithm, ue_p->ciphering_algorithm,
ue_p->integrity_algorithm); ue_p->integrity_algorithm);
uint8_t security_mode = /* RRCReestablishment is integrity protected but not ciphered,
enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4); * so let's configure only integrity protection right now.
* Ciphering is enabled below, after generating RRCReestablishment.
*/
security_parameters.integrity_algorithm = ue_p->integrity_algorithm;
security_parameters.ciphering_algorithm = 0;
/* SRBs */ /* SRBs */
for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) { for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) {
if (ue_p->Srb[srb_id].Active) if (ue_p->Srb[srb_id].Active)
nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc); nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, true, &security_parameters);
} }
/* Re-establish PDCP for SRB1, according to 5.3.7.4 of 3GPP TS 38.331 */ /* Re-establish PDCP for SRB1, according to 5.3.7.4 of 3GPP TS 38.331 */
nr_pdcp_reestablishment(ue_p->rrc_ue_id, 1, true); nr_pdcp_reestablishment(ue_p->rrc_ue_id,
1,
true,
&security_parameters);
/* F1AP DL RRC Message Transfer */ /* F1AP DL RRC Message Transfer */
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data); RETURN_IF_INVALID_ASSOC_ID(ue_data);
...@@ -912,6 +920,14 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context ...@@ -912,6 +920,14 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
.old_gNB_DU_ue_id = &old_gNB_DU_ue_id}; .old_gNB_DU_ue_id = &old_gNB_DU_ue_id};
deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id}; deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id};
nr_pdcp_data_req_srb(ue_p->rrc_ue_id, DCCH, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); nr_pdcp_data_req_srb(ue_p->rrc_ue_id, DCCH, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data);
/* RRCReestablishment has been generated, let's enable ciphering now. */
security_parameters.ciphering_algorithm = ue_p->ciphering_algorithm;
/* SRBs */
for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) {
if (ue_p->Srb[srb_id].Active)
nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, true, &security_parameters);
}
} }
/// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request. /// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request.
...@@ -933,9 +949,6 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co ...@@ -933,9 +949,6 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
ue_p->Srb[1].Active = 1; ue_p->Srb[1].Active = 1;
uint8_t send_security_mode_command = false;
nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
...@@ -966,7 +979,13 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co ...@@ -966,7 +979,13 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
*/ */
int srb_id = 2; int srb_id = 2;
if (ue_p->Srb[srb_id].Active) { if (ue_p->Srb[srb_id].Active) {
nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true); nr_pdcp_entity_security_keys_and_algos_t security_parameters;
security_parameters.ciphering_algorithm = ue_p->ciphering_algorithm;
security_parameters.integrity_algorithm = ue_p->integrity_algorithm;
nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, security_parameters.ciphering_key);
nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, security_parameters.integrity_key);
nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true, &security_parameters);
} }
/* PDCP Reestablishment of DRBs according to 5.3.5.6.5 of 3GPP TS 38.331 (over E1) */ /* PDCP Reestablishment of DRBs according to 5.3.5.6.5 of 3GPP TS 38.331 (over E1) */
cuup_notify_reestablishment(rrc, ue_p); cuup_notify_reestablishment(rrc, ue_p);
...@@ -1891,6 +1910,11 @@ static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f ...@@ -1891,6 +1910,11 @@ static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f
DevAssert(req.numPDUSessionsMod > 0); DevAssert(req.numPDUSessionsMod > 0);
DevAssert(req.numPDUSessions == 0); DevAssert(req.numPDUSessions == 0);
req.cipheringAlgorithm = rrc->security.do_drb_ciphering ? UE->ciphering_algorithm : 0;
req.integrityProtectionAlgorithm = rrc->security.do_drb_integrity ? UE->integrity_algorithm : 0;
nr_derive_key(UP_ENC_ALG, req.cipheringAlgorithm, UE->kgnb, (uint8_t *)req.encryptionKey);
nr_derive_key(UP_INT_ALG, req.integrityProtectionAlgorithm, UE->kgnb, (uint8_t *)req.integrityProtectionKey);
// send the E1 bearer modification request message to update F1-U tunnel info // send the E1 bearer modification request message to update F1-U tunnel info
sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE);
rrc->cucp_cuup.bearer_context_mod(assoc_id, &req); rrc->cucp_cuup.bearer_context_mod(assoc_id, &req);
......
...@@ -135,33 +135,29 @@ nr_rrc_pdcp_config_security( ...@@ -135,33 +135,29 @@ nr_rrc_pdcp_config_security(
) )
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0};
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
uint8_t kUPenc[NR_K_KEY_SIZE] = {0};
//uint8_t *k_kdf = NULL; //uint8_t *k_kdf = NULL;
static int print_keys= 1; static int print_keys= 1;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
/* Derive the keys from kgnb */ /* Derive the keys from kgnb */
if (UE->Srb[1].Active || UE->Srb[2].Active) { nr_pdcp_entity_security_keys_and_algos_t security_parameters;
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); /* set ciphering algorithm depending on 'enable_ciphering' */
} security_parameters.ciphering_algorithm = enable_ciphering ? UE->ciphering_algorithm : 0;
security_parameters.integrity_algorithm = UE->integrity_algorithm;
nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); /* use current ciphering algorithm, independently of 'enable_ciphering' to derive ciphering key */
nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, security_parameters.ciphering_key);
nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, security_parameters.integrity_key);
if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) {
if (print_keys == 1 ) { if (print_keys == 1 ) {
print_keys =0; print_keys =0;
LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, UE->kgnb, 32, "\nKgNB:"); LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, UE->kgnb, 32, "\nKgNB:");
LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 16,"\nKRRCenc:" ); LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, security_parameters.ciphering_key, 16,"\nKRRCenc:" );
LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 16,"\nKRRCint:" ); LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, security_parameters.integrity_key, 16,"\nKRRCint:" );
} }
} }
uint8_t security_mode = nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, true, &security_parameters);
enable_ciphering ? UE->ciphering_algorithm | (UE->integrity_algorithm << 4) : 0 | (UE->integrity_algorithm << 4);
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, security_mode, kRRCenc, kRRCint, kUPenc);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -126,8 +126,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a ...@@ -126,8 +126,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
protocol_ctxt_t ctxt={0}; protocol_ctxt_t ctxt={0};
uint8_t kUPenc[NR_K_KEY_SIZE] = {0}; nr_pdcp_entity_security_keys_and_algos_t security_parameters = {0};
uint8_t kUPint[NR_K_KEY_SIZE] = {0};
int i; int i;
gNB_RRC_UE_t *UE = &ue_context_p->ue_context; gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
...@@ -218,8 +217,10 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a ...@@ -218,8 +217,10 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
LOG_I(RRC, "selecting integrity algorithm %d\n", UE->integrity_algorithm); LOG_I(RRC, "selecting integrity algorithm %d\n", UE->integrity_algorithm);
/* derive UP security key */ /* derive UP security key */
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); security_parameters.ciphering_algorithm = UE->ciphering_algorithm;
nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, kUPint); security_parameters.integrity_algorithm = UE->integrity_algorithm;
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, security_parameters.ciphering_key);
nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, security_parameters.integrity_key);
e_NR_CipheringAlgorithm cipher_algo; e_NR_CipheringAlgorithm cipher_algo;
switch (UE->ciphering_algorithm) { switch (UE->ciphering_algorithm) {
...@@ -388,9 +389,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a ...@@ -388,9 +389,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
nr_pdcp_add_drbs(ctxt.enb_flag, nr_pdcp_add_drbs(ctxt.enb_flag,
rrc_ue_id, rrc_ue_id,
ue_context_p->ue_context.rb_config->drb_ToAddModList, ue_context_p->ue_context.rb_config->drb_ToAddModList,
(ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, &security_parameters);
kUPenc,
kUPint);
ctxt.rntiMaybeUEid = du_ue_id; ctxt.rntiMaybeUEid = du_ue_id;
// assume only a single bearer // assume only a single bearer
......
This diff is collapsed.
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