Change in osmo-msc[master]: Validate the choosen UTRAN encryption algorithm

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Fri Nov 5 09:48:27 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-msc/+/25832 )

Change subject: Validate the choosen UTRAN encryption algorithm
......................................................................

Validate the choosen UTRAN encryption algorithm

RANAP Security Command can include an encryption IE. If it includes
it the RNC can still ignore it (e.g. unsupported encryption) and
return the Security Command Complete with an choosen encryption IE:
"no encryption".
Validate the encryption element and ensure the encryption is included in
the encryption mask.

Closes: OS#4144
Change-Id: Icfc135c8b8ae862defe7114db492af600c26407f
---
M include/osmocom/msc/ran_msg.h
M src/libmsc/msc_a.c
M src/libmsc/ran_msg_iu.c
M tests/msc_vlr/msc_vlr_test_authen_reuse.c
M tests/msc_vlr/msc_vlr_test_call.c
M tests/msc_vlr/msc_vlr_test_umts_authen.c
M tests/msc_vlr/msc_vlr_tests.c
M tests/msc_vlr/msc_vlr_tests.h
8 files changed, 52 insertions(+), 18 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve



diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h
index 0714607..32b24a0 100644
--- a/include/osmocom/msc/ran_msg.h
+++ b/include/osmocom/msc/ran_msg.h
@@ -216,6 +216,12 @@
 			 * alg_id == 1 means A5/0 i.e. no encryption, alg_id == 4 means A5/3.
 			 * alg_id == 0 means no such IE was present. */
 			uint8_t alg_id;
+			/*! utran integrity protection. 0..15 */
+			int16_t utran_integrity;
+			/*! utran_integrity is in encoded format:
+			 *  utran_integrity == -1 means no such IE was present
+			 *  utran_integrity == 0 means no encryption. */
+			int16_t utran_encryption;
 			const char *imeisv;
 			const struct tlv_p_entry *l3_msg;
 		} cipher_mode_complete;
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index a79cf6a..583f9e7 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -1404,6 +1404,7 @@
 int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
 {
 	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
+	struct gsm_network *net = msc_a_net(msc_a);
 	const struct ran_msg *msg = d->ran_dec;
 	int rc = -99;
 
@@ -1459,7 +1460,25 @@
 			msc_a->geran_encr.alg_id = msg->cipher_mode_complete.alg_id;
 			LOG_MSC_A(msc_a, LOGL_DEBUG, "Cipher Mode Complete: chosen encryption algorithm: A5/%u\n",
 				  msc_a->geran_encr.alg_id - 1);
-		};
+		}
+
+		if (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU) {
+			int16_t utran_encryption;
+
+			/* utran: ensure chosen ciphering mode is allowed
+			 * If the IE is missing (utran_encryption == -1), parse it as no encryption */
+			utran_encryption = msg->cipher_mode_complete.utran_encryption;
+			if (utran_encryption == -1)
+				utran_encryption = 0;
+			if ((net->uea_encryption_mask & (1 << utran_encryption)) == 0) {
+				/* cipher disallowed */
+				LOG_MSC_A(msc_a, LOGL_ERROR, "Cipher Mode Complete: RNC chosen forbidden ciphering UEA%d\n",
+					  msg->cipher_mode_complete.utran_encryption);
+				vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_REJECT);
+				rc = 0;
+				break;
+			}
+		}
 		vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_COMPL);
 		rc = 0;
 
diff --git a/src/libmsc/ran_msg_iu.c b/src/libmsc/ran_msg_iu.c
index 7b3dd1c..81147cf 100644
--- a/src/libmsc/ran_msg_iu.c
+++ b/src/libmsc/ran_msg_iu.c
@@ -211,12 +211,20 @@
 		ranap_free_rab_setupormodifieditemies(&setup_ies);
 }
 
-static void ran_iu_decode_security_mode_complete(struct ran_dec *ran_iu_decode)
+static void ran_iu_decode_security_mode_complete(struct ran_dec *ran_iu_decode,  const RANAP_SecurityModeCompleteIEs_t *ies)
 {
 	struct ran_msg ran_dec_msg = {
 		.msg_type = RAN_MSG_CIPHER_MODE_COMPLETE,
 		.msg_name = "RANAP SecurityModeControl successfulOutcome",
+		.cipher_mode_complete = {
+			.utran_integrity = ies->chosenIntegrityProtectionAlgorithm,
+			.utran_encryption = -1,
+		},
 	};
+
+	if (ies->presenceMask & SECURITYMODECOMPLETEIES_RANAP_CHOSENENCRYPTIONALGORITHM_PRESENT)
+		ran_dec_msg.cipher_mode_complete.utran_encryption = ies->chosenEncryptionAlgorithm;
+
 	ran_decoded(ran_iu_decode, &ran_dec_msg);
 }
 
@@ -272,7 +280,7 @@
 	case RANAP_ProcedureCode_id_SecurityModeControl:
 		switch (message->direction) {
 		case RANAP_RANAP_PDU_PR_successfulOutcome:
-			ran_iu_decode_security_mode_complete(ran_iu_decode);
+			ran_iu_decode_security_mode_complete(ran_iu_decode, &message->msg.securityModeCompleteIEs);
 			return;
 		case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
 			ran_iu_decode_security_mode_reject(ran_iu_decode);
diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.c b/tests/msc_vlr/msc_vlr_test_authen_reuse.c
index f8f9383..870f993 100644
--- a/tests/msc_vlr/msc_vlr_test_authen_reuse.c
+++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.c
@@ -99,7 +99,7 @@
 
 		btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
 		gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
-		ms_sends_security_mode_complete();
+		ms_sends_security_mode_complete(1);
 		VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
 		VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
 	}
@@ -170,7 +170,7 @@
 			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 			btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
-			ms_sends_security_mode_complete();
+			ms_sends_security_mode_complete(1);
 			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 		}
 
@@ -239,7 +239,7 @@
 			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 			btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
-			ms_sends_security_mode_complete();
+			ms_sends_security_mode_complete(1);
 			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 		}
 
diff --git a/tests/msc_vlr/msc_vlr_test_call.c b/tests/msc_vlr/msc_vlr_test_call.c
index 9ab1066..a547935 100644
--- a/tests/msc_vlr/msc_vlr_test_call.c
+++ b/tests/msc_vlr/msc_vlr_test_call.c
@@ -128,7 +128,7 @@
 
 	btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
 	gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
-	ms_sends_security_mode_complete();
+	ms_sends_security_mode_complete(1);
 	VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
 	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
 
@@ -197,7 +197,7 @@
 	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 	btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
-	ms_sends_security_mode_complete();
+	ms_sends_security_mode_complete(1);
 	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 	BTW("a call is initiated");
@@ -317,7 +317,7 @@
 
 	btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
 	dtap_expect_tx("0305" /* CC: Setup */);
-	ms_sends_security_mode_complete();
+	ms_sends_security_mode_complete(1);
 
 	btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
 	expect_crcx(RTP_TO_RAN);
@@ -420,7 +420,7 @@
 
 	btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
 	dtap_expect_tx("0305" /* CC: Setup */);
-	ms_sends_security_mode_complete();
+	ms_sends_security_mode_complete(1);
 
 	btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
 	expect_crcx(RTP_TO_RAN);
@@ -509,7 +509,7 @@
 	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 	btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
-	ms_sends_security_mode_complete();
+	ms_sends_security_mode_complete(1);
 	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 	BTW("a call is initiated");
@@ -605,7 +605,7 @@
 	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 	btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
-	ms_sends_security_mode_complete();
+	ms_sends_security_mode_complete(1);
 	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 	BTW("a call is initiated");
diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.c b/tests/msc_vlr/msc_vlr_test_umts_authen.c
index e462ef4..655183b 100644
--- a/tests/msc_vlr/msc_vlr_test_umts_authen.c
+++ b/tests/msc_vlr/msc_vlr_test_umts_authen.c
@@ -138,7 +138,7 @@
 
 			btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
 			gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
-			ms_sends_security_mode_complete();
+			ms_sends_security_mode_complete(1);
 			VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
 			VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
 		}
@@ -211,7 +211,7 @@
 			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 
 			btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
-			ms_sends_security_mode_complete();
+			ms_sends_security_mode_complete(1);
 			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
 		}
 	} else {
@@ -278,7 +278,7 @@
 
 			btw("MS sends SecurityModeControl acceptance, VLR accepts and sends SMS");
 			dtap_expect_tx(sms);
-			ms_sends_security_mode_complete();
+			ms_sends_security_mode_complete(1);
 		}
 	} else {
 		/* Encryption disabled */
@@ -530,7 +530,7 @@
 
 			btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
 			gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
-			ms_sends_security_mode_complete();
+			ms_sends_security_mode_complete(1);
 			VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
 			VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
 		}
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
index 102fba7..fbd2540 100644
--- a/tests/msc_vlr/msc_vlr_tests.c
+++ b/tests/msc_vlr/msc_vlr_tests.c
@@ -986,12 +986,13 @@
 		g_msub = NULL;
 }
 
-void ms_sends_security_mode_complete()
+void ms_sends_security_mode_complete(uint8_t utran_encryption)
 {
 	struct ran_msg ran_dec;
 
 	ran_dec = (struct ran_msg){
 		.msg_type = RAN_MSG_CIPHER_MODE_COMPLETE,
+		.cipher_mode_complete.utran_encryption = utran_encryption,
 	};
 	fake_msc_a_ran_dec(&ran_dec);
 
diff --git a/tests/msc_vlr/msc_vlr_tests.h b/tests/msc_vlr/msc_vlr_tests.h
index 23dc9da..a2b2f22 100644
--- a/tests/msc_vlr/msc_vlr_tests.h
+++ b/tests/msc_vlr/msc_vlr_tests.h
@@ -184,7 +184,7 @@
 void ms_sends_msg(const char *hex);
 void ms_sends_classmark_update(const struct osmo_gsm48_classmark *classmark);
 void ms_sends_ciphering_mode_complete(const char *inner_nas_msg);
-void ms_sends_security_mode_complete();
+void ms_sends_security_mode_complete(uint8_t utran_encryption);
 void ms_sends_assignment_complete(enum mgcp_codecs assigned_codec);
 void gsup_rx(const char *rx_hex, const char *expect_tx_hex);
 void send_sms(struct vlr_subscr *receiver,

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-msc/+/25832
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Change-Id: Icfc135c8b8ae862defe7114db492af600c26407f
Gerrit-Change-Number: 25832
Gerrit-PatchSet: 4
Gerrit-Owner: lynxis lazus <lynxis at fe80.eu>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211105/7ac948ae/attachment.htm>


More information about the gerrit-log mailing list