msc_a,vlr: add ciphering_required (accurately named)

For establishing Layer 3, pass a flag from msc_a to VLR that indicates
to fail if encryption is not possible.

An earlier patch [1] renamed a previously existing flag ciphering_required
to try_ciphering, because the naming was not accurate. This new flag now
indicates exactly what its name suggests.

This new flag is needed for upcoming patch [2] to distinguish between
optional and mandatory encryption.

[1] Ia55085e3b36feb275bcf92fc91a4be7d1c24a6b9
[2] I5feda196fa481dd8a46b0e4721c64b7c6600f0d1

Related: OS#4830
Change-Id: I52090c5f5db997030da7c2ed9beca9c51f55f4cf
diff --git a/include/osmocom/msc/msc_a.h b/include/osmocom/msc/msc_a.h
index ad41d73..0bd72cb 100644
--- a/include/osmocom/msc/msc_a.h
+++ b/include/osmocom/msc/msc_a.h
@@ -181,6 +181,7 @@
 unsigned int msc_a_pending_cm_service_req_count(struct msc_a *msc_a, enum osmo_cm_service_type type);
 void msc_a_pending_cm_service_req_del(struct msc_a *msc_a, enum osmo_cm_service_type type);
 bool msc_a_try_ciphering(const struct msc_a *msc_a);
+bool msc_a_require_ciphering(const struct msc_a *msc_a);
 
 #define msc_a_ran_down(A,B,C) \
 	_msc_a_ran_down(A,B,C, __FILE__, __LINE__)
diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h
index db9c72b..8f2417a 100644
--- a/include/osmocom/msc/vlr.h
+++ b/include/osmocom/msc/vlr.h
@@ -300,6 +300,7 @@
 	       const struct osmo_location_area_id *new_lai,
 	       bool authentication_required,
 	       bool try_ciphering,
+	       bool ciphering_required,
 	       uint8_t key_seq,
 	       bool is_r99, bool is_utran,
 	       bool assign_tmsi);
@@ -464,6 +465,7 @@
 		 const struct osmo_location_area_id *lai,
 		 bool authentication_required,
 		 bool try_ciphering,
+		 bool ciphering_required,
 		 uint8_t key_seq,
 		 bool is_r99, bool is_utran);
 
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index 3c60b1f..af20b38 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -418,6 +418,7 @@
 				&old_lai, &msc_a->via_cell.lai,
 				is_utran || net->authentication_required,
 				msc_a_try_ciphering(msc_a),
+				msc_a_require_ciphering(msc_a),
 				lu->key_seq,
 				osmo_gsm48_classmark1_is_r99(&lu->classmark1),
 				is_utran,
@@ -819,6 +820,7 @@
 			 &mi, &msc_a->via_cell.lai,
 			 is_utran || net->authentication_required,
 			 msc_a_try_ciphering(msc_a),
+			 msc_a_require_ciphering(msc_a),
 			 req->cipher_key_seq,
 			 osmo_gsm48_classmark2_is_r99(cm2, cm2_len),
 			 is_utran);
@@ -945,6 +947,7 @@
 			 &mi, &msc_a->via_cell.lai,
 			 is_utran || net->authentication_required,
 			 msc_a_try_ciphering(msc_a),
+			 msc_a_require_ciphering(msc_a),
 			 req->cipher_key_seq,
 			 osmo_gsm48_classmark2_is_r99(cm2, cm2_len),
 			 is_utran);
@@ -1307,6 +1310,7 @@
 			 VLR_PR_ARQ_T_PAGING_RESP, 0, &mi, &msc_a->via_cell.lai,
 			 is_utran || net->authentication_required,
 			 msc_a_try_ciphering(msc_a),
+			 msc_a_require_ciphering(msc_a),
 			 pr->key_seq,
 			 osmo_gsm48_classmark2_is_r99(cm2, classmark2_len),
 			 is_utran);
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index fad5b77..7ce70c9 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -116,6 +116,18 @@
 		return net->a5_encryption_mask > 0x1;
 }
 
+bool msc_a_require_ciphering(const struct msc_a *msc_a)
+{
+	struct gsm_network *net = msc_a_net(msc_a);
+	bool is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
+	if (is_utran)
+		return net->uea_encryption_mask
+			&& ((net->uea_encryption_mask & (1 << OSMO_UTRAN_UEA0)) == 0);
+	else
+		return net->a5_encryption_mask
+			&& ((net->a5_encryption_mask & 0x1) == 0);
+}
+
 static void update_counters(struct osmo_fsm_inst *fi, bool conn_accepted)
 {
 	struct msc_a *msc_a = fi->priv;
diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c
index 5b8d9bb..b2836d7 100644
--- a/src/libvlr/vlr_access_req_fsm.c
+++ b/src/libvlr/vlr_access_req_fsm.c
@@ -68,6 +68,7 @@
 	struct osmo_location_area_id lai;
 	bool authentication_required;
 	bool try_ciphering;
+	bool ciphering_required;
 	uint8_t key_seq;
 	bool is_r99;
 	bool is_utran;
@@ -635,6 +636,7 @@
 		 const struct osmo_location_area_id *lai,
 		 bool authentication_required,
 		 bool try_ciphering,
+		 bool ciphering_required,
 		 uint8_t key_seq,
 		 bool is_r99, bool is_utran)
 {
@@ -658,6 +660,7 @@
 	par->parent_event_data = parent_event_data;
 	par->authentication_required = authentication_required;
 	par->try_ciphering = try_ciphering;
+	par->ciphering_required = ciphering_required;
 	par->key_seq = key_seq;
 	par->is_r99 = is_r99;
 	par->is_utran = is_utran;
diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c
index 7a1c445..5461a6b 100644
--- a/src/libvlr/vlr_lu_fsm.c
+++ b/src/libvlr/vlr_lu_fsm.c
@@ -677,6 +677,7 @@
 	struct osmo_location_area_id new_lai;
 	bool authentication_required;
 	bool try_ciphering;
+	bool ciphering_required;
 	uint8_t key_seq;
 	bool is_r99;
 	bool is_utran;
@@ -1476,6 +1477,7 @@
 	       const struct osmo_location_area_id *new_lai,
 	       bool authentication_required,
 	       bool try_ciphering,
+	       bool ciphering_required,
 	       uint8_t key_seq,
 	       bool is_r99, bool is_utran,
 	       bool assign_tmsi)
@@ -1500,6 +1502,7 @@
 	lfp->parent_event_data = parent_event_data;
 	lfp->authentication_required = authentication_required;
 	lfp->try_ciphering = try_ciphering;
+	lfp->ciphering_required = ciphering_required;
 	lfp->key_seq = key_seq;
 	lfp->is_r99 = is_r99;
 	lfp->is_utran = is_utran;