Commit ca187dcc authored by winckel's avatar winckel

Added processing of security key and corrected use of security algorithms...

Added processing of security key and corrected use of security algorithms information received from S1AP.

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4537 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent b83aca1d
......@@ -183,6 +183,9 @@ typedef struct eNB_RRC_UE_INFO_s {
/* Information from S1AP initial_context_setup_req */
uint32_t eNB_ue_s1ap_id :24;
security_capabilities_t security_capabilities;
/* Number of e_rab to be setup in the list */
uint8_t nb_of_e_rabs;
/* list of e_rab to be setup by RRC layers */
......
......@@ -457,6 +457,7 @@ static void rrc_lite_eNB_init_security(u8 Mod_id, u8 UE_index)
for (i = 0; i < 32; i++) {
sprintf(&ascii_buffer[2 * i], "%02X", eNB_rrc_inst[Mod_id].kenb[UE_index][i]);
}
ascii_buffer[2 * i] = '\0';
LOG_T(RRC, "[OSA][MOD %02d][UE %02d] kenb = %s\n", Mod_id, UE_index, ascii_buffer);
#endif
......@@ -2408,13 +2409,6 @@ char openair_rrc_lite_eNB_init (u8 Mod_id)
for (j = 0; j < NUMBER_OF_UE_MAX; j++)
eNB_rrc_inst[Mod_id].Info.UE[j].Status = RRC_IDLE; //CH_READY;
/* Init security parameters */
for (j = 0; j < NUMBER_OF_UE_MAX; j++) {
eNB_rrc_inst[Mod_id].ciphering_algorithm[j] = SecurityAlgorithmConfig__cipheringAlgorithm_eea2;
eNB_rrc_inst[Mod_id].integrity_algorithm[j] = SecurityAlgorithmConfig__integrityProtAlgorithm_eia2;
rrc_lite_eNB_init_security(Mod_id, j);
}
#if defined(ENABLE_USE_MME)
/* Connect eNB to MME */
if (EPC_MODE_ENABLED > 0)
......@@ -2427,7 +2421,16 @@ char openair_rrc_lite_eNB_init (u8 Mod_id)
}
# endif
}
else
#endif
{
/* Init security parameters */
for (j = 0; j < NUMBER_OF_UE_MAX; j++) {
eNB_rrc_inst[Mod_id].ciphering_algorithm[j] = SecurityAlgorithmConfig__cipheringAlgorithm_eea2;
eNB_rrc_inst[Mod_id].integrity_algorithm[j] = SecurityAlgorithmConfig__integrityProtAlgorithm_eia2;
rrc_lite_eNB_init_security(Mod_id, j);
}
}
eNB_rrc_inst[Mod_id].Info.Nb_ue = 0;
......
......@@ -55,6 +55,20 @@
/* Value to indicate an invalid UE initial id */
static const uint16_t UE_INITIAL_ID_INVALID = 0;
/* Masks for S1AP Encryption algorithms, EEA0 is always supported (not coded) */
static const uint16_t S1AP_ENCRYPTION_EEA1_MASK = 0x1;
static const uint16_t S1AP_ENCRYPTION_EEA2_MASK = 0x2;
/* Masks for S1AP Integrity algorithms, EIA0 is always supported (not coded) */
static const uint16_t S1AP_INTEGRITY_EIA1_MASK = 0x1;
static const uint16_t S1AP_INTEGRITY_EIA2_MASK = 0x2;
#ifdef Rel10
# define INTEGRITY_ALGORITHM_NONE SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920
#else
# define INTEGRITY_ALGORITHM_NONE SecurityAlgorithmConfig__integrityProtAlgorithm_reserved
#endif
# if defined(ENABLE_ITTI)
/*! \fn uint16_t get_next_ue_initial_id(uint8_t mod_id)
*\brief provide an UE initial ID for S1AP initial communication.
......@@ -84,11 +98,12 @@ static uint8_t get_UE_index_from_initial_id(uint8_t mod_id, uint16_t ue_initial_
uint8_t ue_index;
DevCheck(mod_id < NB_eNB_INST, mod_id, NB_eNB_INST, 0);
LOG_I(RRC, "get_UE_index_from_initial_id eNB %d, ue_initial_id %d\n", mod_id, ue_initial_id);
LOG_D(RRC, "[eNB %d] get_UE_index_from_initial_id: ue_initial_id %d\n", ue_initial_id);
for (ue_index = 0; ue_index < NUMBER_OF_UE_MAX; ue_index++) {
/* Check if this UE is in use */
LOG_I(RRC, " UE %d: 0x%" PRIx64 " %d\n", ue_index, eNB_rrc_inst[mod_id].Info.UE_list[ue_index], eNB_rrc_inst[mod_id].Info.UE[ue_index].ue_initial_id);
LOG_D(RRC, "[eNB %d][UE %d] 0x%" PRIx64 " %d\n", mod_id, ue_index,
eNB_rrc_inst[mod_id].Info.UE_list[ue_index], eNB_rrc_inst[mod_id].Info.UE[ue_index].ue_initial_id);
if (eNB_rrc_inst[mod_id].Info.UE_list[ue_index] != 0) {
/* Check if the initial id match */
......@@ -110,11 +125,12 @@ static uint8_t get_UE_index_from_eNB_ue_s1ap_id(uint8_t mod_id, uint32_t eNB_ue_
uint8_t ue_index;
DevCheck(mod_id < NB_eNB_INST, mod_id, NB_eNB_INST, 0);
LOG_I(RRC, "get_UE_index_from_eNB_ue_s1ap_id eNB %d, eNB_ue_s1ap_id %d\n", mod_id, eNB_ue_s1ap_id);
LOG_D(RRC, "[eNB %d] get_UE_index_from_eNB_ue_s1ap_id: eNB_ue_s1ap_id %d\n", mod_id, eNB_ue_s1ap_id);
for (ue_index = 0; ue_index < NUMBER_OF_UE_MAX; ue_index++) {
/* Check if this UE is in use */
LOG_I(RRC, " UE %d: 0x%" PRIx64 " %d\n", ue_index, eNB_rrc_inst[mod_id].Info.UE_list[ue_index], eNB_rrc_inst[mod_id].Info.UE[ue_index].eNB_ue_s1ap_id);
LOG_D(RRC, "[eNB %d][UE %d] 0x%" PRIx64 " %d\n", mod_id, ue_index,
eNB_rrc_inst[mod_id].Info.UE_list[ue_index], eNB_rrc_inst[mod_id].Info.UE[ue_index].eNB_ue_s1ap_id);
if (eNB_rrc_inst[mod_id].Info.UE_list[ue_index] != 0) {
/* Check if the initial id match */
......@@ -149,6 +165,101 @@ static uint8_t get_UE_index_from_s1ap_ids(uint8_t mod_id, uint16_t ue_initial_id
return ue_index;
}
/*! \fn e_SecurityAlgorithmConfig__cipheringAlgorithm rrc_eNB_select_ciphering(uint16_t algorithms)
*\brief analyze available encryption algorithms bit mask and return the relevant one.
*\param algorithms The bit mask of available algorithms received from S1AP.
*\return the selected algorithm.
*/
static e_SecurityAlgorithmConfig__cipheringAlgorithm rrc_eNB_select_ciphering(uint16_t algorithms) {
if (algorithms & S1AP_ENCRYPTION_EEA2_MASK) {
return SecurityAlgorithmConfig__cipheringAlgorithm_eea2;
}
#if defined (ENABLE_SNOW_3G)
if (algorithms & S1AP_ENCRYPTION_EEA1_MASK) {
return SecurityAlgorithmConfig__cipheringAlgorithm_eea1;
}
#endif
return SecurityAlgorithmConfig__cipheringAlgorithm_eea0;
}
/*! \fn e_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_integrity(uint16_t algorithms)
*\brief analyze available integrity algorithms bit mask and return the relevant one.
*\param algorithms The bit mask of available algorithms received from S1AP.
*\return the selected algorithm.
*/
static e_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_integrity(uint16_t algorithms) {
if (algorithms & S1AP_INTEGRITY_EIA2_MASK) {
return SecurityAlgorithmConfig__integrityProtAlgorithm_eia2;
}
#if defined (ENABLE_SNOW_3G)
if (algorithms & S1AP_INTEGRITY_EIA1_MASK) {
return SecurityAlgorithmConfig__integrityProtAlgorithm_eia1;
}
#endif
return INTEGRITY_ALGORITHM_NONE;
}
/*! \fn int rrc_eNB_process_security (uint8_t mod_id, uint8_t ue_index, security_capabilities_t *security_capabilities)
*\brief save and analyze available security algorithms bit mask and select relevant ones.
*\param mod_id Instance ID of eNB.
*\param ue_index Instance ID of UE in the eNB.
*\param security_capabilities The security capabilities received from S1AP.
*\return TRUE if at least one algorithm has been changed else FALSE.
*/
static int rrc_eNB_process_security (uint8_t mod_id, uint8_t ue_index, security_capabilities_t *security_capabilities) {
int changed = FALSE;
e_SecurityAlgorithmConfig__cipheringAlgorithm cipheringAlgorithm;
e_SecurityAlgorithmConfig__integrityProtAlgorithm integrityProtAlgorithm;
/* Save security parameters */
eNB_rrc_inst[mod_id].Info.UE[ue_index].security_capabilities = *security_capabilities;
/* Select relevant algorithms */
cipheringAlgorithm = rrc_eNB_select_ciphering (eNB_rrc_inst[mod_id].Info.UE[ue_index].security_capabilities.encryption_algorithms);
if (eNB_rrc_inst[mod_id].ciphering_algorithm[ue_index] != cipheringAlgorithm) {
eNB_rrc_inst[mod_id].ciphering_algorithm[ue_index] = cipheringAlgorithm;
changed = TRUE;
}
integrityProtAlgorithm = rrc_eNB_select_integrity (eNB_rrc_inst[mod_id].Info.UE[ue_index].security_capabilities.integrity_algorithms);
if (eNB_rrc_inst[mod_id].integrity_algorithm[ue_index] != integrityProtAlgorithm) {
eNB_rrc_inst[mod_id].integrity_algorithm[ue_index] = integrityProtAlgorithm;
changed = TRUE;
}
LOG_I (RRC, "[eNB %d][UE %d] Selected security algorithms: %x, %x, %s",
mod_id, ue_index, cipheringAlgorithm, integrityProtAlgorithm, changed ? "changed" : "same");
return changed;
}
/*! \fn void process_eNB_security_key (uint8_t mod_id, uint8_t ue_index, uint8_t *security_key)
*\brief save security key.
*\param mod_id Instance ID of eNB.
*\param ue_index Instance ID of UE in the eNB.
*\param security_key The security key received from S1AP.
*/
static void process_eNB_security_key (uint8_t mod_id, uint8_t ue_index, uint8_t *security_key) {
#if defined(ENABLE_SECURITY)
char ascii_buffer[65];
uint8_t i;
/* Saves the security key */
memcpy (eNB_rrc_inst[mod_id].kenb[ue_index], security_key, SECURITY_KEY_LENGTH);
for (i = 0; i < 32; i++) {
sprintf(&ascii_buffer[2 * i], "%02X", eNB_rrc_inst[mod_id].kenb[ue_index][i]);
}
ascii_buffer[2 * i] = '\0';
LOG_I (RRC, "[eNB %d][UE %d] Saved security key %s", mod_id, ue_index, ascii_buffer);
#endif
}
/*------------------------------------------------------------------------------*/
void rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(uint8_t mod_id, uint8_t ue_index) {
eNB_RRC_UE_INFO *UE_info = &eNB_rrc_inst[mod_id].Info.UE[ue_index];
......@@ -321,13 +432,13 @@ int rrc_eNB_process_S1AP_DOWNLINK_NAS(MessageDef *msg_p, const char *msg_name, i
eNB_ue_s1ap_id = S1AP_DOWNLINK_NAS (msg_p).eNB_ue_s1ap_id;
ue_index = get_UE_index_from_s1ap_ids (instance, ue_initial_id, eNB_ue_s1ap_id);
LOG_I(RRC, "Received %s: instance %d, ue_initial_id %d, eNB_ue_s1ap_id %d, ue_index %d\n", msg_name, instance, ue_initial_id, eNB_ue_s1ap_id, ue_index);
LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, ue_index %d\n", instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, ue_index);
if (ue_index == UE_INDEX_INVALID) {
/* Can not associate this message to an UE index, send a failure to S1AP and discard it! */
MessageDef *msg_fail_p;
LOG_W(RRC, "In S1AP_DOWNLINK_NAS: unknown UE from S1AP ids (%d, %d) for eNB %d\n", ue_initial_id, eNB_ue_s1ap_id, instance);
LOG_W(RRC, "[eNB %d] In S1AP_DOWNLINK_NAS: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id);
msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_NAS_NON_DELIVERY_IND);
S1AP_NAS_NON_DELIVERY_IND (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
......@@ -364,14 +475,14 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
eNB_ue_s1ap_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id;
ue_index = get_UE_index_from_s1ap_ids (instance, ue_initial_id, eNB_ue_s1ap_id);
LOG_I(RRC, "Received %s: instance %d, ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d, ue_index %d\n",
msg_name, instance, ue_initial_id, eNB_ue_s1ap_id, S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_e_rabs, ue_index);
LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d, ue_index %d\n",
instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_e_rabs, ue_index);
if (ue_index == UE_INDEX_INVALID) {
/* Can not associate this message to an UE index, send a failure to S1AP and discard it! */
MessageDef *msg_fail_p;
LOG_W(RRC, "In S1AP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from S1AP ids (%d, %d) for eNB %d\n", ue_initial_id, eNB_ue_s1ap_id, instance);
LOG_W(RRC, "[eNB %d] In S1AP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id);
msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_INITIAL_CONTEXT_SETUP_FAIL);
S1AP_INITIAL_CONTEXT_SETUP_FAIL (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
......@@ -399,18 +510,19 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
/* TODO parameters yet to process ... */
{
S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_ambr;
S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key;
}
/* Save security parameters, assuming S1AP and RRC are using the same coding for all configuration */
eNB_rrc_inst[instance].ciphering_algorithm[ue_index] =
S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_capabilities.encryption_algorithms;
eNB_rrc_inst[instance].ciphering_algorithm[ue_index] =
S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_capabilities.integrity_algorithms;
rrc_eNB_process_security (instance, ue_index, &S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_capabilities);
process_eNB_security_key (instance, ue_index, S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key);
{
uint8_t send_security_mode_command = TRUE;
// TODO evaluate if security mode command should be skipped
if ((eNB_rrc_inst[instance].ciphering_algorithm[ue_index] == SecurityAlgorithmConfig__cipheringAlgorithm_eea0)
&& (eNB_rrc_inst[instance].integrity_algorithm[ue_index] == INTEGRITY_ALGORITHM_NONE)) {
send_security_mode_command = FALSE;
}
if (send_security_mode_command) {
rrc_eNB_generate_SecurityModeCommand (instance, 0 /* TODO put frame number ! */, ue_index);
......@@ -435,7 +547,7 @@ int rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char
/* Can not associate this message to an UE index, send a failure to S1AP and discard it! */
MessageDef *msg_fail_p;
LOG_W(RRC, "In S1AP_UE_CTXT_MODIFICATION_REQ: unknown UE from eNB_ue_s1ap_id (%d) for eNB %d\n", eNB_ue_s1ap_id, instance);
LOG_W(RRC, "[eNB %d] In S1AP_UE_CTXT_MODIFICATION_REQ: unknown UE from eNB_ue_s1ap_id (%d) for eNB %d\n", instance, eNB_ue_s1ap_id);
msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UE_CTXT_MODIFICATION_FAIL);
S1AP_UE_CTXT_MODIFICATION_FAIL (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
......@@ -450,24 +562,22 @@ int rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char
/* TODO parameters yet to process ... */
{
if (S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).present & S1AP_UE_CONTEXT_MODIFICATION_SECURITY_KEY) {
S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).security_key;
}
if (S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).present & S1AP_UE_CONTEXT_MODIFICATION_UE_AMBR) {
S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).ue_ambr;
}
}
if (S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).present & S1AP_UE_CONTEXT_MODIFICATION_UE_SECU_CAP) {
/* Save security parameters, assuming S1AP and RRC are using the same coding for all configuration */
eNB_rrc_inst[instance].ciphering_algorithm[ue_index] =
S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).security_capabilities.encryption_algorithms;
eNB_rrc_inst[instance].ciphering_algorithm[ue_index] =
S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).security_capabilities.integrity_algorithms;
/* transmit the new security parameters to UE */
rrc_eNB_generate_SecurityModeCommand (instance, 0 /* TODO put frame number ! */, ue_index);
if (rrc_eNB_process_security (instance, ue_index, &S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).security_capabilities)) {
/* transmit the new security parameters to UE */
rrc_eNB_generate_SecurityModeCommand (instance, 0 /* TODO put frame number ! */, ue_index);
}
}
if (S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).present & S1AP_UE_CONTEXT_MODIFICATION_SECURITY_KEY) {
process_eNB_security_key (instance, ue_index, S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).security_key);
/* TODO reconfigure lower layers... */
}
/* Send the response */
......@@ -496,8 +606,7 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char *
/* Can not associate this message to an UE index, send a failure to S1AP and discard it! */
MessageDef *msg_fail_p;
LOG_W(RRC,
"In S1AP_UE_CONTEXT_RELEASE_REQ: unknown UE from eNB_ue_s1ap_id (%d) for eNB %d\n", eNB_ue_s1ap_id, instance);
LOG_W(RRC, "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_REQ: unknown UE from eNB_ue_s1ap_id (%d) for eNB %d\n", instance, eNB_ue_s1ap_id);
msg_fail_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_RESP); /* TODO change message ID. */
S1AP_UE_CONTEXT_RELEASE_RESP(msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_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