Commit 93f59582 authored by Cedric Roux's avatar Cedric Roux

cleanup nr_pdcp_config_set_security()

- make it work for SRB or DRB
- adapt callers of this function
- cleanup key derivation: the User Plane keys are generated at some places
  but are not used, remove the generation
parent 514537e6
......@@ -330,9 +330,9 @@ 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,
char *integrity_key,
const uint8_t *integrity_key,
int ciphering_algorithm,
char *ciphering_key)
const uint8_t *ciphering_key)
{
if (integrity_algorithm != -1)
entity->integrity_algorithm = integrity_algorithm;
......@@ -663,9 +663,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
ret->is_gnb = is_gnb;
nr_pdcp_entity_set_security(ret,
integrity_algorithm, (char *)integrity_key,
ciphering_algorithm, (char *)ciphering_key);
nr_pdcp_entity_set_security(ret, integrity_algorithm, integrity_key, ciphering_algorithm, ciphering_key);
return ret;
}
......@@ -101,9 +101,9 @@ typedef struct nr_pdcp_entity_t {
*/
void (*set_security)(struct nr_pdcp_entity_t *entity,
int integrity_algorithm,
char *integrity_key,
const uint8_t *integrity_key,
int ciphering_algorithm,
char *ciphering_key);
const uint8_t *ciphering_key);
/* check_integrity is used by RRC */
bool (*check_integrity)(struct nr_pdcp_entity_t *entity,
......
......@@ -1027,10 +1027,10 @@ 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 uint8_t security_modeP,
uint8_t *const kRRCenc_pP,
uint8_t *const kRRCint_pP,
uint8_t *const kUPenc_pP)
const bool is_srb,
const uint8_t security_mode,
const uint8_t *kenc,
const uint8_t *kint)
{
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
......@@ -1041,20 +1041,17 @@ void nr_pdcp_config_set_security(ue_id_t 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, true);
rb = nr_pdcp_get_rb(ue, rb_id, is_srb);
if (rb == NULL) {
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;
}
integrity_algorithm = (security_modeP>>4) & 0xf;
ciphering_algorithm = security_modeP & 0x0f;
rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
ciphering_algorithm, (char *)kRRCenc_pP);
integrity_algorithm = (security_mode >> 4) & 0xf;
ciphering_algorithm = security_mode & 0x0f;
rb->set_security(rb, integrity_algorithm, kint, ciphering_algorithm, kenc);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
......@@ -1240,7 +1237,13 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id)
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,
int ciphering_algorithm,
const uint8_t *ciphering_key,
int integrity_algorithm,
const uint8_t *integrity_key)
{
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
......@@ -1251,7 +1254,7 @@ void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag)
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);
rb->reestablish_entity(rb, ciphering_algorithm, ciphering_key, integrity_algorithm, integrity_key);
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);
......
......@@ -82,10 +82,10 @@ void add_srb(int is_gnb,
void nr_pdcp_config_set_security(ue_id_t ue_id,
const rb_id_t rb_id,
const uint8_t security_modeP,
uint8_t *const kRRCenc_pP,
uint8_t *const kRRCint_pP,
uint8_t *const kUPenc_pP);
const bool is_srb,
const uint8_t security_mode,
const uint8_t *kenc,
const uint8_t *kint);
bool nr_pdcp_check_integrity_srb(ue_id_t ue_id,
int srb_id,
......
......@@ -898,7 +898,7 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
/* 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, security_mode, kRRCenc, kRRCint, kUPenc);
nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, true, security_mode, kRRCenc, kRRCint);
}
/* 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);
......
......@@ -137,16 +137,11 @@ 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;
static int print_keys= 1;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
/* Derive the keys from kgnb */
if (UE->Srb[1].Active || UE->Srb[2].Active) {
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc);
}
nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint);
......@@ -161,7 +156,7 @@ nr_rrc_pdcp_config_security(
uint8_t security_mode =
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);
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, true, security_mode, kRRCenc, kRRCint);
}
//------------------------------------------------------------------------------
......
......@@ -638,7 +638,7 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti)
// apply the specified configuration defined in 9.2.1 for SRB1
nr_rlc_reconfigure_entity(rrc->ue_id, lc_id, NULL);
// suspend integrity protection and ciphering for SRB1
nr_pdcp_config_set_security(rrc->ue_id, srb_id, 0, NULL, NULL, NULL);
nr_pdcp_config_set_security(rrc->ue_id, srb_id, true, 0, NULL, NULL);
// resume SRB1
rrc->Srb[srb_id] = RB_ESTABLISHED;
break;
......@@ -1048,20 +1048,18 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
}
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0};
uint8_t kUPenc[NR_K_KEY_SIZE] = {0};
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
nr_derive_key(UP_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kUPenc);
nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, kRRCint);
log_dump(NR_RRC, ue_rrc->kgnb, 32, LOG_DUMP_CHAR, "deriving kRRCenc, kRRCint and kUPenc from KgNB=");
log_dump(NR_RRC, ue_rrc->kgnb, 32, LOG_DUMP_CHAR, "deriving kRRCenc, kRRCint from KgNB=");
/* for SecurityModeComplete, ciphering is not activated yet, only integrity */
uint8_t security_mode = ue_rrc->integrityProtAlgorithm << 4;
// configure lower layers to apply SRB integrity protection and ciphering
for (int i = 1; i < NR_NUM_SRB; i++) {
if (ue_rrc->Srb[i] == RB_ESTABLISHED)
nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, kRRCenc, kRRCint, kUPenc);
nr_pdcp_config_set_security(ue_rrc->ue_id, i, true, security_mode, kRRCenc, kRRCint);
}
NR_UL_DCCH_Message_t ul_dcch_msg = {0};
......@@ -1097,7 +1095,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
security_mode = 0;
for (int i = 1; i < NR_NUM_SRB; i++) {
if (ue_rrc->Srb[i] == RB_ESTABLISHED)
nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, NULL, NULL, NULL);
nr_pdcp_config_set_security(ue_rrc->ue_id, i, true, security_mode, NULL, NULL);
}
srb_id = 1; // SecurityModeFailure in SRB1
......@@ -1144,7 +1142,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
for (int i = 1; i < NR_NUM_SRB; i++) {
if (ue_rrc->Srb[i] == RB_ESTABLISHED)
/* pass NULL to keep current keys */
nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, NULL, NULL, NULL);
nr_pdcp_config_set_security(ue_rrc->ue_id, i, true, security_mode, NULL, NULL);
}
}
......@@ -1550,15 +1548,11 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc,
// update the K gNB key based on the current K gNB key or the NH, using the stored nextHopChainingCount value
nr_derive_key_ng_ran_star(rrc->phyCellID, rrc->arfcn_ssb, rrc->kgnb, rrc->kgnb);
// derive the K RRCenc and K UPenc keys associated with the previously configured cipheringAlgorithm
// derive the K RRCint and K UPint keys associated with the previously configured integrityProtAlgorithm
uint8_t kRRCenc[16] = {0};
uint8_t kRRCint[16] = {0};
uint8_t kUPenc[16] = {0};
uint8_t kUPint[16] = {0};
// derive the K RRCenc key associated with the previously configured cipheringAlgorithm
// derive the K RRCint key associated with the previously configured integrityProtAlgorithm
uint8_t kRRCenc[NR_K_KEY_SIZE] = {0};
uint8_t kRRCint[NR_K_KEY_SIZE] = {0};
nr_derive_key(UP_ENC_ALG, rrc->cipheringAlgorithm, rrc->kgnb, kUPenc);
nr_derive_key(UP_INT_ALG, rrc->integrityProtAlgorithm, rrc->kgnb, kUPint);
nr_derive_key(RRC_ENC_ALG, rrc->cipheringAlgorithm, rrc->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, rrc->integrityProtAlgorithm, rrc->kgnb, kRRCint);
......@@ -1570,7 +1564,7 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc,
int srb_id = 1;
int security_mode = (rrc->integrityProtAlgorithm << 4)
| rrc->cipheringAlgorithm;
nr_pdcp_config_set_security(rrc->ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc);
nr_pdcp_config_set_security(rrc->ue_id, srb_id, true, security_mode, kRRCenc, kRRCint);
// release the measurement gap configuration indicated by the measGapConfig, if configured
rrcPerNB_t *rrcNB = rrc->perNB + gNB_index;
......
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