Change in osmo-msc[master]: libvlr: Allow 2G auth tuples to be re-used without going through AUTH

Harald Welte gerrit-no-reply at lists.osmocom.org
Tue Mar 19 15:24:01 UTC 2019


Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/13248 )

Change subject: libvlr: Allow 2G auth tuples to be re-used without going through AUTH
......................................................................

libvlr: Allow 2G auth tuples to be re-used without going through AUTH

If the key_seq we get in the first messages matches the last_tuple, then
both we and the MS already know the key to use and we don't need the
AUTH REQUEST/RESPONSE cycle.

Security wise ... not so good, and so IMHO the 'auth required' option
in the MSC should always be set. But this allows to turn on ciphering on
a channel without doing any MM transaction, and so the MS doesn't turn
on the T3240 timer which allows to have a ciphered silent-call channel
that won't timeout.

Change-Id: Ief840a2ae7a0ffd2bf0bf726f209a79e3f787646
Signed-off-by: Sylvain Munaut <tnt at 246tNt.com>
---
M include/osmocom/msc/vlr.h
M src/libmsc/gsm_04_08.c
M src/libvlr/vlr_access_req_fsm.c
M src/libvlr/vlr_auth_fsm.c
M src/libvlr/vlr_auth_fsm.h
M src/libvlr/vlr_lu_fsm.c
6 files changed, 40 insertions(+), 2 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h
index 3529640..d2d59c7 100644
--- a/include/osmocom/msc/vlr.h
+++ b/include/osmocom/msc/vlr.h
@@ -303,6 +303,7 @@
 	       const struct osmo_location_area_id *new_lai,
 	       bool authentication_required,
 	       bool ciphering_required,
+	       uint8_t key_seq,
 	       bool is_r99, bool is_utran,
 	       bool assign_tmsi);
 
@@ -446,6 +447,7 @@
 		 const struct osmo_location_area_id *lai,
 		 bool authentication_required,
 		 bool ciphering_required,
+		 uint8_t key_seq,
 		 bool is_r99, bool is_utran);
 
 void vlr_parq_cancel(struct osmo_fsm_inst *fi,
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index c6e5528..09744db 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -433,6 +433,7 @@
 				&old_lai, &new_lai,
 				is_utran || conn->network->authentication_required,
 				is_utran || conn->network->a5_encryption_mask > 0x01,
+				lu->key_seq,
 				classmark1_is_r99(&lu->classmark1),
 				is_utran,
 				net->vlr->cfg.assign_tmsi);
@@ -820,6 +821,7 @@
 			 VLR_PR_ARQ_T_CM_SERV_REQ, mi-1, &lai,
 			 is_utran || conn->network->authentication_required,
 			 is_utran || conn->network->a5_encryption_mask > 0x01,
+			 req->cipher_key_seq,
 			 classmark2_is_r99(classmark2, classmark2_len),
 			 is_utran);
 
@@ -1178,6 +1180,8 @@
 {
 	struct gsm_network *net = conn->network;
 	struct gsm48_hdr *gh = msgb_l3(msg);
+	struct gsm48_pag_resp *pr =
+			(struct gsm48_pag_resp *)gh->data;
 	uint8_t classmark2_len = gh->data[1];
 	uint8_t *classmark2 = gh->data+2;
 	uint8_t *mi_lv = classmark2 + classmark2_len;
@@ -1209,6 +1213,7 @@
 			 VLR_PR_ARQ_T_PAGING_RESP, mi_lv, &lai,
 			 is_utran || conn->network->authentication_required,
 			 is_utran || conn->network->a5_encryption_mask > 0x01,
+			 pr->key_seq,
 			 classmark2_is_r99(classmark2, classmark2_len),
 			 is_utran);
 
diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c
index 3b40285..26db42c 100644
--- a/src/libvlr/vlr_access_req_fsm.c
+++ b/src/libvlr/vlr_access_req_fsm.c
@@ -67,6 +67,7 @@
 	struct osmo_location_area_id lai;
 	bool authentication_required;
 	bool ciphering_required;
+	uint8_t key_seq;
 	bool is_r99;
 	bool is_utran;
 	bool implicitly_accepted_parq_by_ciphering_cmd;
@@ -316,7 +317,8 @@
 	/* The cases where the authentication procedure should be used
 	 * are defined in 3GPP TS 33.102 */
 	/* For now we use a default value passed in to vlr_lu_fsm(). */
-	return par->authentication_required || par->ciphering_required;
+	return par->authentication_required ||
+		(par->ciphering_required && !auth_try_reuse_tuple(par->vsub, par->key_seq));
 }
 
 /* after the IMSI is known */
@@ -528,6 +530,7 @@
 		.out_state_mask = S(PR_ARQ_S_DONE) |
 				  S(PR_ARQ_S_WAIT_OBTAIN_IMSI) |
 				  S(PR_ARQ_S_WAIT_AUTH) |
+				  S(PR_ARQ_S_WAIT_CIPH) |
 				  S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
 				  S(PR_ARQ_S_WAIT_SUB_PRES) |
 				  S(PR_ARQ_S_WAIT_TRACE_SUB) |
@@ -540,6 +543,7 @@
 		.in_event_mask = S(PR_ARQ_E_ID_IMSI),
 		.out_state_mask = S(PR_ARQ_S_DONE) |
 				  S(PR_ARQ_S_WAIT_AUTH) |
+				  S(PR_ARQ_S_WAIT_CIPH) |
 				  S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
 				  S(PR_ARQ_S_WAIT_SUB_PRES) |
 				  S(PR_ARQ_S_WAIT_TRACE_SUB) |
@@ -637,6 +641,7 @@
 		 const struct osmo_location_area_id *lai,
 		 bool authentication_required,
 		 bool ciphering_required,
+		 uint8_t key_seq,
 		 bool is_r99, bool is_utran)
 {
 	struct osmo_fsm_inst *fi;
@@ -660,6 +665,7 @@
 	par->parent_event_data = parent_event_data;
 	par->authentication_required = authentication_required;
 	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_auth_fsm.c b/src/libvlr/vlr_auth_fsm.c
index ccf3660..6026510 100644
--- a/src/libvlr/vlr_auth_fsm.c
+++ b/src/libvlr/vlr_auth_fsm.c
@@ -629,3 +629,18 @@
 
 	return fi;
 }
+
+bool auth_try_reuse_tuple(struct vlr_subscr *vsub, uint8_t key_seq)
+{
+	int max_reuse_count = vsub->vlr->cfg.auth_tuple_max_reuse_count;
+	struct vlr_auth_tuple *at = vsub->last_tuple;
+
+	if (!at)
+		return false;
+	if ((max_reuse_count >= 0) && (at->use_count > max_reuse_count))
+		return false;
+	if (at->key_seq != key_seq)
+		return false;
+	at->use_count++;
+	return true;
+}
diff --git a/src/libvlr/vlr_auth_fsm.h b/src/libvlr/vlr_auth_fsm.h
index 618462f..1f2cb49 100644
--- a/src/libvlr/vlr_auth_fsm.h
+++ b/src/libvlr/vlr_auth_fsm.h
@@ -35,3 +35,5 @@
 				     uint32_t parent_term_event,
 				     bool is_r99,
 				     bool is_utran);
+
+bool auth_try_reuse_tuple(struct vlr_subscr *vsub, uint8_t key_seq);
diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c
index 8152d20..7ddf455 100644
--- a/src/libvlr/vlr_lu_fsm.c
+++ b/src/libvlr/vlr_lu_fsm.c
@@ -685,6 +685,7 @@
 	struct osmo_location_area_id new_lai;
 	bool authentication_required;
 	bool ciphering_required;
+	uint8_t key_seq;
 	bool is_r99;
 	bool is_utran;
 	bool assign_tmsi;
@@ -705,7 +706,8 @@
 	/* The cases where the authentication procedure should be used
 	 * are defined in 3GPP TS 33.102 */
 	/* For now we use a default value passed in to vlr_lu_fsm(). */
-	return lfp->authentication_required || lfp->ciphering_required;
+	return lfp->authentication_required ||
+		(lfp->ciphering_required && !auth_try_reuse_tuple(lfp->vsub, lfp->key_seq));
 }
 
 /* Determine if ciphering is required */
@@ -1316,6 +1318,7 @@
 				  S(VLR_ULA_S_WAIT_PVLR) |
 				  S(VLR_ULA_S_WAIT_IMSI) |
 				  S(VLR_ULA_S_WAIT_AUTH) |
+				  S(VLR_ULA_S_WAIT_CIPH) |
 				  S(VLR_ULA_S_WAIT_HLR_UPD) |
 				  S(VLR_ULA_S_DONE),
 		.name = OSMO_STRINGIFY(VLR_ULA_S_IDLE),
@@ -1326,6 +1329,7 @@
 		.out_state_mask = S(VLR_ULA_S_WAIT_PVLR) |
 				  S(VLR_ULA_S_WAIT_IMSI) |
 				  S(VLR_ULA_S_WAIT_AUTH) |
+				  S(VLR_ULA_S_WAIT_CIPH) |
 				  S(VLR_ULA_S_WAIT_HLR_UPD) |
 				  S(VLR_ULA_S_DONE),
 		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMEISV),
@@ -1336,6 +1340,7 @@
 				 S(VLR_ULA_E_SEND_ID_NACK),
 		.out_state_mask = S(VLR_ULA_S_WAIT_IMSI) |
 				  S(VLR_ULA_S_WAIT_AUTH) |
+				  S(VLR_ULA_S_WAIT_CIPH) |
 				  S(VLR_ULA_S_DONE),
 		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_PVLR),
 		.action = lu_fsm_wait_pvlr,
@@ -1360,6 +1365,7 @@
 	[VLR_ULA_S_WAIT_IMSI] = {
 		.in_event_mask = S(VLR_ULA_E_ID_IMSI),
 		.out_state_mask = S(VLR_ULA_S_WAIT_AUTH) |
+				  S(VLR_ULA_S_WAIT_CIPH) |
 				  S(VLR_ULA_S_WAIT_HLR_UPD) |
 				  S(VLR_ULA_S_DONE),
 		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMSI),
@@ -1439,6 +1445,7 @@
 	       const struct osmo_location_area_id *new_lai,
 	       bool authentication_required,
 	       bool ciphering_required,
+	       uint8_t key_seq,
 	       bool is_r99, bool is_utran,
 	       bool assign_tmsi)
 {
@@ -1462,6 +1469,7 @@
 	lfp->parent_event_data = parent_event_data;
 	lfp->authentication_required = authentication_required;
 	lfp->ciphering_required = ciphering_required;
+	lfp->key_seq = key_seq;
 	lfp->is_r99 = is_r99;
 	lfp->is_utran = is_utran;
 	lfp->assign_tmsi = assign_tmsi;

-- 
To view, visit https://gerrit.osmocom.org/13248
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ief840a2ae7a0ffd2bf0bf726f209a79e3f787646
Gerrit-Change-Number: 13248
Gerrit-PatchSet: 2
Gerrit-Owner: tnt <tnt at 246tNt.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: tnt <tnt at 246tNt.com>
Gerrit-CC: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190319/ea776408/attachment.html>


More information about the gerrit-log mailing list