From 182b05bd5c6493ec5d7b2ac40ed59ac33bcc4142 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 22 Jan 2025 16:06:36 +0100 Subject: [PATCH] e1: security information is optional in bearer modification Check if the IE is memory allocated to deal with presence/absence of this information element in Bearer Context Modification Request and add encoding/decoding in the code. Note that for decoding the integrity settings may be absent, in which case we consider NIA0 to be used (no integrity protection). To be refined if needed. And for encoding, we always encode integrity settings, even if it's NIA0. May also be refined if needed. --- openair2/E1AP/e1ap.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 72eff658cb..c17f54be11 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -451,6 +451,21 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_mod_req_t *const ieC2->criticality = E1AP_Criticality_reject; ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_up_ue_id; + /* optional */ + /* Security Information */ + if (bearerCxt->secInfo) { + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ie); + ie->id = E1AP_ProtocolIE_ID_id_SecurityInformation; + ie->criticality = E1AP_Criticality_reject; + ie->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_SecurityInformation; + E1AP_SecurityAlgorithm_t *securityAlgorithm = &ie->value.choice.SecurityInformation.securityAlgorithm; + E1AP_UPSecuritykey_t *uPSecuritykey = &ie->value.choice.SecurityInformation.uPSecuritykey; + securityAlgorithm->cipheringAlgorithm = bearerCxt->secInfo->cipheringAlgorithm; + OCTET_STRING_fromBuf(&uPSecuritykey->encryptionKey, bearerCxt->secInfo->encryptionKey, E1AP_SECURITY_KEY_SIZE); + asn1cCallocOne(securityAlgorithm->integrityProtectionAlgorithm, bearerCxt->secInfo->integrityProtectionAlgorithm); + asn1cCalloc(uPSecuritykey->integrityProtectionKey, protKey); + OCTET_STRING_fromBuf(protKey, bearerCxt->secInfo->integrityProtectionKey, E1AP_SECURITY_KEY_SIZE); + } /* optional */ /* c3. E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3); @@ -606,6 +621,26 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID; break; + case E1AP_ProtocolIE_ID_id_SecurityInformation: { + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_SecurityInformation); + E1AP_SecurityInformation_t *sec = &ie->value.choice.SecurityInformation; + DevAssert(sec->uPSecuritykey.encryptionKey.size == E1AP_SECURITY_KEY_SIZE); + DevAssert(sec->uPSecuritykey.integrityProtectionKey == NULL + || sec->uPSecuritykey.integrityProtectionKey->size == E1AP_SECURITY_KEY_SIZE); + bearerCxt->secInfo = malloc_or_fail(sizeof(*bearerCxt->secInfo)); + bearerCxt->secInfo->cipheringAlgorithm = sec->securityAlgorithm.cipheringAlgorithm; + bearerCxt->secInfo->integrityProtectionAlgorithm = sec->securityAlgorithm.integrityProtectionAlgorithm == NULL + ? 0 + : *sec->securityAlgorithm.integrityProtectionAlgorithm; + memcpy(bearerCxt->secInfo->encryptionKey, sec->uPSecuritykey.encryptionKey.buf, E1AP_SECURITY_KEY_SIZE); + if (sec->securityAlgorithm.integrityProtectionAlgorithm == NULL) + memset(bearerCxt->secInfo->integrityProtectionKey, 0, E1AP_SECURITY_KEY_SIZE); + else + memcpy(bearerCxt->secInfo->integrityProtectionKey, sec->uPSecuritykey.integrityProtectionKey->buf, E1AP_SECURITY_KEY_SIZE); + break; + } + case E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest: DevAssert(ie->criticality == E1AP_Criticality_reject); DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest);