Commit 0b4335ac authored by Cedric Roux's avatar Cedric Roux

NSA: some work on security (for PDCP)

- compute correct kgNB
- propagate properly NR security capabilities of an UE
  (involves: rrc, s1ap, x2ap)
parent 39ab3c1e
...@@ -155,6 +155,11 @@ typedef struct security_capabilities_s { ...@@ -155,6 +155,11 @@ typedef struct security_capabilities_s {
uint16_t integrity_algorithms; uint16_t integrity_algorithms;
} security_capabilities_t; } security_capabilities_t;
typedef struct nr_security_capabilities_s {
uint16_t encryption_algorithms;
uint16_t integrity_algorithms;
} nr_security_capabilities_t;
/* Provides the establishment cause for the RRC connection request as provided /* Provides the establishment cause for the RRC connection request as provided
* by the upper layers. W.r.t. the cause value names: highPriorityAccess * by the upper layers. W.r.t. the cause value names: highPriorityAccess
* concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for * concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for
...@@ -538,6 +543,9 @@ typedef struct s1ap_initial_context_setup_req_s { ...@@ -538,6 +543,9 @@ typedef struct s1ap_initial_context_setup_req_s {
uint8_t nb_of_e_rabs; uint8_t nb_of_e_rabs;
/* list of e_rab to be setup by RRC layers */ /* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB]; e_rab_t e_rab_param[S1AP_MAX_E_RAB];
/* NR Security algorithms (if any, set to 0 if not present) */
nr_security_capabilities_t nr_security_capabilities;
} s1ap_initial_context_setup_req_t; } s1ap_initial_context_setup_req_t;
typedef struct tai_plmn_identity_s { typedef struct tai_plmn_identity_s {
......
...@@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { ...@@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s {
/* used for RRC->X2AP in source eNB */ /* used for RRC->X2AP in source eNB */
int rnti; int rnti;
security_capabilities_t security_capabilities; nr_security_capabilities_t security_capabilities;
/* SgNB Security Key */ /* SgNB Security Key */
uint8_t kgnb[32]; uint8_t kgnb[32];
......
...@@ -546,6 +546,13 @@ typedef struct rrc_gummei_s { ...@@ -546,6 +546,13 @@ typedef struct rrc_gummei_s {
uint16_t mme_group_id; uint16_t mme_group_id;
} rrc_gummei_t; } rrc_gummei_t;
typedef struct {
uint16_t ciphering_algorithms;
uint16_t integrity_algorithms;
uint16_t sk_counter;
uint8_t kgNB[32];
} lte_rrc_nr_security_t;
typedef struct eNB_RRC_UE_s { typedef struct eNB_RRC_UE_s {
uint8_t primaryCC_id; uint8_t primaryCC_id;
LTE_SCellToAddMod_r10_t sCell_config[2]; LTE_SCellToAddMod_r10_t sCell_config[2];
...@@ -615,6 +622,9 @@ typedef struct eNB_RRC_UE_s { ...@@ -615,6 +622,9 @@ typedef struct eNB_RRC_UE_s {
security_capabilities_t security_capabilities; security_capabilities_t security_capabilities;
/* security capabilities and settings for an UE in ENDC mode */
lte_rrc_nr_security_t nr_security;
int next_hop_chain_count; int next_hop_chain_count;
uint8_t next_security_key[SECURITY_KEY_LENGTH]; uint8_t next_security_key[SECURITY_KEY_LENGTH];
......
...@@ -4665,11 +4665,20 @@ rrc_eNB_process_MeasurementReport( ...@@ -4665,11 +4665,20 @@ rrc_eNB_process_MeasurementReport(
msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ); msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ);
memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t)); memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t));
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti; X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = ue_context_pP->ue_context.nr_security.ciphering_algorithms;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = ue_context_pP->ue_context.nr_security.integrity_algorithms;
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ue_context_pP->ue_context.nr_security.kgNB, 32);
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size); memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size; X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId
= measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId; = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId;
//For the moment we have a single E-RAB which will be the one to be added to the gNB //For the moment we have a single E-RAB which will be the one to be added to the gNB
//Not sure how to select bearers to be added if there are multiple. //Not sure how to select bearers to be added if there are multiple.
X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1; X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1;
......
...@@ -1045,6 +1045,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char ...@@ -1045,6 +1045,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
} }
} }
ue_context_p->ue_context.nr_security.ciphering_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.encryption_algorithms;
ue_context_p->ue_context.nr_security.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.integrity_algorithms;
/* let's initialize sk_counter to 0 */
ue_context_p->ue_context.nr_security.sk_counter = 0;
/* let's compute kgNB */
derive_skgNB(ue_context_p->ue_context.kenb,
ue_context_p->ue_context.nr_security.sk_counter,
ue_context_p->ue_context.nr_security.kgNB);
// in case, send the S1SP initial context response if it is not sent with the attach complete message // in case, send the S1SP initial context response if it is not sent with the attach complete message
if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) { if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause);
......
...@@ -53,6 +53,8 @@ typedef enum { ...@@ -53,6 +53,8 @@ typedef enum {
//int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB); //int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB);
int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
const uint8_t key[32], uint8_t **out); const uint8_t key[32], uint8_t **out);
int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
......
...@@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB) ...@@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
return 0; return 0;
} }
*/ */
int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB)
{
uint8_t *out;
uint8_t s[5];
/* FC is 0x1c (see 3gpp 33.401 annex A.15) */
s[0] = 0x1c;
/* put sk_counter */
s[1] = (sk_counter >> 8) & 0xff;
s[2] = sk_counter & 0xff;
/* put length of sk_counter (2) */
s[3] = 0x00;
s[4] = 0x02;
kdf(s, 5, keNB, 32, &out, 32);
memcpy(skgNB, out, 32);
free(out);
return 0;
}
...@@ -864,22 +864,36 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, ...@@ -864,22 +864,36 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms);
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms);
/* id-SecurityKey : Copy the security key */
} else {/* ie != NULL */ } else {/* ie != NULL */
return -1; return -1;
} }
/* id-SecurityKey : Copy the security key */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_SecurityKey, true); S1AP_ProtocolIE_ID_id_SecurityKey, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size);
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
} else {/* ie != NULL */ } else {/* ie != NULL */
return -1; return -1;
} }
/* id-NRUESecurityCapabilities */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false);
if (ie != NULL) {
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
} else {
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0;
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0;
}
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
return 0; return 0;
} }
......
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