[MERGED] osmo-msc[master]: Permit a set of multiple different A5 ciphers

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/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Sun Jan 28 00:09:44 UTC 2018


Harald Welte has submitted this change and it was merged.

Change subject: Permit a set of multiple different A5 ciphers
......................................................................


Permit a set of multiple different A5 ciphers

So far, the administrator had to pick one particular cipher which
would then be used throughout all subscribers/phones. This is a bit
impractical, as e.g. not all phones support A5/3.  Extend the VTY
command syntax in a backwards-compatible way to permit for multiple
ciphers.

NOTE: Like the previous code, OsmoMSC does *not yet check* whether
the configured cipher is compatible with the MS capabilities as
reported in CLASSMARK!  The network hence might choose an algorithm
not supported by the phone.  Fixing this is subject to another patch.

Closes: OS#2460
Change-Id: I79a4e2892eb5fbecc3d84e11dceffb7149db264b
---
M include/osmocom/msc/gsm_data.h
M src/libcommon-cs/common_cs.c
M src/libcommon-cs/common_cs_vty.c
M src/libmsc/gsm_04_08.c
M src/libmsc/msc_vty.c
M tests/msc_vlr/msc_vlr_test_gsm_ciph.c
M tests/msc_vlr/msc_vlr_test_gsm_ciph.err
M tests/msc_vlr/msc_vlr_tests.c
8 files changed, 49 insertions(+), 30 deletions(-)

Approvals:
  Vadim Yanitskiy: Looks good to me, but someone else must approve
  Neels Hofmeyr: Looks good to me, but someone else must approve
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index e987136..27324d7 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -299,7 +299,8 @@
 	regex_t authorized_regexp;
 	char *authorized_reg_str;
 	enum gsm48_reject_value reject_cause;
-	int a5_encryption;
+	/* bit-mask of permitted encryption algorithms. LSB=A5/0, MSB=A5/7 */
+	uint8_t a5_encryption_mask;
 	bool authentication_required;
 	int neci;
 	int send_mm_info;
diff --git a/src/libcommon-cs/common_cs.c b/src/libcommon-cs/common_cs.c
index 41c456e..170b62a 100644
--- a/src/libcommon-cs/common_cs.c
+++ b/src/libcommon-cs/common_cs.c
@@ -56,6 +56,8 @@
 
 	net->country_code = country_code;
 	net->network_code = network_code;
+	/* Permit a compile-time default of A5/3 and A5/1 */
+	net->a5_encryption_mask = (1 << 3) | (1 << 1);
 
 	/* Use 30 min periodic update interval as sane default */
 	net->t3212 = 5;
diff --git a/src/libcommon-cs/common_cs_vty.c b/src/libcommon-cs/common_cs_vty.c
index 4754531..8c9f127 100644
--- a/src/libcommon-cs/common_cs_vty.c
+++ b/src/libcommon-cs/common_cs_vty.c
@@ -155,15 +155,20 @@
 
 DEFUN(cfg_net_encryption,
       cfg_net_encryption_cmd,
-      "encryption a5 (0|1|2|3)",
+      "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
 	"Encryption options\n"
-	"A5 encryption\n" "A5/0: No encryption\n"
-	"A5/1: Encryption\n" "A5/2: Export-grade Encryption\n"
-	"A5/3: 'New' Secure Encryption\n")
+	"GSM A5 Air Interface Encryption\n"
+	"A5/n Algorithm Number\n"
+	"A5/n Algorithm Number\n"
+	"A5/n Algorithm Number\n"
+	"A5/n Algorithm Number\n")
 {
 	struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+	unsigned int i;
 
-	gsmnet->a5_encryption = atoi(argv[0]);
+	gsmnet->a5_encryption_mask = 0;
+	for (i = 0; i < argc; i++)
+		gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
 
 	return CMD_SUCCESS;
 }
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index c37aeb7..3574583 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -339,7 +339,7 @@
 				net->vlr, conn, vlr_lu_type, tmsi, imsi,
 				&old_lai, &new_lai,
 				is_utran || conn->network->authentication_required,
-				is_utran || conn->network->a5_encryption,
+				is_utran || conn->network->a5_encryption_mask > 0x01,
 				classmark_is_r99(&conn->classmark),
 				is_utran,
 				net->vlr->cfg.assign_tmsi);
@@ -723,7 +723,7 @@
 			 net->vlr, conn,
 			 VLR_PR_ARQ_T_CM_SERV_REQ, mi-1, &lai,
 			 is_utran || conn->network->authentication_required,
-			 is_utran || conn->network->a5_encryption,
+			 is_utran || conn->network->a5_encryption_mask > 0x01,
 			 classmark_is_r99(&conn->classmark),
 			 is_utran);
 
@@ -1127,7 +1127,7 @@
 			 net->vlr, conn,
 			 VLR_PR_ARQ_T_PAGING_RESP, mi_lv, &lai,
 			 is_utran || conn->network->authentication_required,
-			 is_utran || conn->network->a5_encryption,
+			 is_utran || conn->network->a5_encryption_mask > 0x01,
 			 classmark_is_r99(&conn->classmark),
 			 is_utran);
 
@@ -3447,10 +3447,15 @@
 		DEBUGP(DMM, "-> CIPHER MODE COMMAND %s\n",
 		       vlr_subscr_name(conn->vsub));
 		{
+			struct gsm_network *net = conn->network;
 			struct gsm0808_encrypt_info ei;
+			int i, j = 0;
 
-			ei.perm_algo[0] = vlr_ciph_to_gsm0808_alg_id(conn->network->a5_encryption);
-			ei.perm_algo_len = 1;
+			for (i = 0; i < 8; i++) {
+				if (net->a5_encryption_mask & (1 << i))
+					ei.perm_algo[j++] = vlr_ciph_to_gsm0808_alg_id(i);
+			}
+			ei.perm_algo_len = j;
 
 			/* In case of UMTS AKA, the Kc for ciphering must be derived from the 3G auth
 			 * tokens.  tuple->vec.kc was calculated from the GSM algorithm and is not
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 82608c6..faf17ec 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -1,7 +1,7 @@
 /* MSC interface to quagga VTY */
 /* (C) 2016 by sysmocom s.m.f.c. GmbH <info at sysmocom.de>
  * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c)
- * (C) 2009 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2009-2017 by Harald Welte <laforge at gnumonks.org>
  * (C) 2009-2011 by Holger Hans Peter Freyther
  * All Rights Reserved
  *
@@ -160,6 +160,7 @@
 static int config_write_net(struct vty *vty)
 {
 	struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+	int i;
 
 	vty_out(vty, "network%s", VTY_NEWLINE);
 	vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
@@ -169,7 +170,12 @@
 	vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE);
 	vty_out(vty, " location updating reject cause %u%s",
 		gsmnet->reject_cause, VTY_NEWLINE);
-	vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
+	vty_out(vty, " encryption a5");
+	for (i = 0; i < 8; i++) {
+		if (gsmnet->a5_encryption_mask & (1 << i))
+			vty_out(vty, " %u", i);
+	}
+	vty_out(vty, "%s", VTY_NEWLINE);
 	vty_out(vty, " authentication %s%s",
 		gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
 	vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode),
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
index e0bd967..42e620a 100644
--- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
@@ -31,7 +31,7 @@
 	comment_start();
 
 	/* implicit: net->authentication_required = true; */
-	net->a5_encryption = VLR_CIPH_A5_1;
+	net->a5_encryption_mask = (1 << 1);
 
 	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
 	lu_result_sent = RES_NONE;
@@ -243,7 +243,7 @@
 	comment_start();
 
 	/* implicit: net->authentication_required = true; */
-	net->a5_encryption = VLR_CIPH_A5_1;
+	net->a5_encryption_mask = (1 << 1);
 	net->vlr->cfg.assign_tmsi = true;
 
 	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
@@ -482,7 +482,7 @@
 	comment_start();
 
 	/* implicit: net->authentication_required = true; */
-	net->a5_encryption = VLR_CIPH_A5_1;
+	net->a5_encryption_mask = (1 << 1);
 	net->vlr->cfg.check_imei_rqd = true;
 
 	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
@@ -584,7 +584,7 @@
 	comment_start();
 
 	/* implicit: net->authentication_required = true; */
-	net->a5_encryption = VLR_CIPH_A5_1;
+	net->a5_encryption_mask = (1 << 1);
 	net->vlr->cfg.retrieve_imeisv_ciphered = true;
 
 	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
@@ -682,7 +682,7 @@
 	comment_start();
 
 	/* implicit: net->authentication_required = true; */
-	net->a5_encryption = VLR_CIPH_A5_1;
+	net->a5_encryption_mask = (1 << 1);
 	net->vlr->cfg.assign_tmsi = true;
 	net->vlr->cfg.check_imei_rqd = true;
 
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
index 0e9d996..cb9091c 100644
--- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
@@ -62,7 +62,7 @@
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=0
+- sending Ciphering Mode Command for IMSI:901700000004620: ciphers=0x02 kc=61855fb81fc2a800 retrieve_imeisv=0
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
 DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF IMSI:901700000004620: MSC conn use - dtap == 1 (0x4)
@@ -225,7 +225,7 @@
 DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED
 DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
 DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for MSISDN:46071: cipher=VLR_CIPH_A5_1 kc=07fa7502e07e1c00 retrieve_imeisv=0
+- sending Ciphering Mode Command for MSISDN:46071: ciphers=0x02 kc=07fa7502e07e1c00 retrieve_imeisv=0
 DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
 DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF MSISDN:46071: MSC conn use - dtap == 1 (0x4)
@@ -370,7 +370,7 @@
 DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED
 DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
 DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for MSISDN:46071: cipher=VLR_CIPH_A5_1 kc=e2b234f807886400 retrieve_imeisv=0
+- sending Ciphering Mode Command for MSISDN:46071: ciphers=0x02 kc=e2b234f807886400 retrieve_imeisv=0
 DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
 DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF MSISDN:46071: MSC conn use - dtap == 1 (0x4)
@@ -547,7 +547,7 @@
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=0
+- sending Ciphering Mode Command for IMSI:901700000004620: ciphers=0x02 kc=61855fb81fc2a800 retrieve_imeisv=0
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
 DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF IMSI:901700000004620: MSC conn use - dtap == 1 (0x4)
@@ -747,7 +747,7 @@
 DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED
 DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
 DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for MSISDN:46071: cipher=VLR_CIPH_A5_1 kc=07fa7502e07e1c00 retrieve_imeisv=0
+- sending Ciphering Mode Command for MSISDN:46071: ciphers=0x02 kc=07fa7502e07e1c00 retrieve_imeisv=0
 DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
 DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF MSISDN:46071: MSC conn use - dtap == 1 (0x4)
@@ -892,7 +892,7 @@
 DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED
 DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
 DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for MSISDN:46071: cipher=VLR_CIPH_A5_1 kc=e2b234f807886400 retrieve_imeisv=0
+- sending Ciphering Mode Command for MSISDN:46071: ciphers=0x02 kc=e2b234f807886400 retrieve_imeisv=0
 DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
 DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF MSISDN:46071: MSC conn use - dtap == 1 (0x4)
@@ -1069,7 +1069,7 @@
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=0
+- sending Ciphering Mode Command for IMSI:901700000004620: ciphers=0x02 kc=61855fb81fc2a800 retrieve_imeisv=0
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
 DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF IMSI:901700000004620: MSC conn use - dtap == 1 (0x4)
@@ -1290,7 +1290,7 @@
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=1
+- sending Ciphering Mode Command for IMSI:901700000004620: ciphers=0x02 kc=61855fb81fc2a800 retrieve_imeisv=1
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
 DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF IMSI:901700000004620: MSC conn use - dtap == 1 (0x4)
@@ -1500,7 +1500,7 @@
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
-- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=0
+- sending Ciphering Mode Command for IMSI:901700000004620: ciphers=0x02 kc=61855fb81fc2a800 retrieve_imeisv=0
 DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
 DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW)
 DREF IMSI:901700000004620: MSC conn use - dtap == 1 (0x4)
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
index b8553b6..e4adfe0 100644
--- a/tests/msc_vlr/msc_vlr_tests.c
+++ b/tests/msc_vlr/msc_vlr_tests.c
@@ -333,7 +333,7 @@
 	}
 
 	net->authentication_required = false;
-	net->a5_encryption = VLR_CIPH_NONE;
+	net->a5_encryption_mask = (1 << 0);
 	net->vlr->cfg.check_imei_rqd = false;
 	net->vlr->cfg.assign_tmsi = false;
 	net->vlr->cfg.retrieve_imeisv_early = false;
@@ -670,10 +670,10 @@
 	struct gsm_subscriber_connection *conn = msc_conn_ref;
 	switch (conn->via_ran) {
 	case RAN_GERAN_A:
-		btw("sending Ciphering Mode Command for %s: cipher=%s kc=%s"
+		btw("sending Ciphering Mode Command for %s: ciphers=0x%02x kc=%s"
 		    " retrieve_imeisv=%d",
 		    vlr_subscr_name(conn->vsub),
-		    vlr_ciph_name(conn->network->a5_encryption),
+		    conn->network->a5_encryption_mask,
 		    osmo_hexdump_nospc(conn->vsub->last_tuple->vec.kc, 8),
 		    retrieve_imeisv);
 		break;

-- 
To view, visit https://gerrit.osmocom.org/5559
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I79a4e2892eb5fbecc3d84e11dceffb7149db264b
Gerrit-PatchSet: 6
Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Vadim Yanitskiy <axilirator at gmail.com>



More information about the gerrit-log mailing list