[PATCH] osmo-sgsn[master]: GERAN: allow GSM SRES on UMTS AKA challenge

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

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Mon Apr 30 23:36:21 UTC 2018


Review at  https://gerrit.osmocom.org/7959

GERAN: allow GSM SRES on UMTS AKA challenge

Store the established security context type (GSM or UMTS) instead of the
boolean flag is_authenticated. Provide the previous boolean query with thin
sgsn_mm_ctx_is_authenticated() function.

Knowing which security context was established will be necessary for OS#3224,
i.e. using the proper ciphering key, which is not yet tested properly, and
probably not correct at this stage.

This change will make new SGSN_Tests.TC_attach_umts_aka_gsm_sres pass.

Related: OS#3193 OS#3224
Change-Id: I36807bad3bc55c0030d4f09cb2c369714f24bec7
---
M include/osmocom/sgsn/gprs_sgsn.h
M src/gprs/gprs_gmm.c
M src/gprs/sgsn_auth.c
M tests/sgsn/sgsn_test.c
4 files changed, 34 insertions(+), 24 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/59/7959/1

diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h
index c47fb09..64e5619 100644
--- a/include/osmocom/sgsn/gprs_sgsn.h
+++ b/include/osmocom/sgsn/gprs_sgsn.h
@@ -224,7 +224,7 @@
 	 * whether one of them can be dropped. */
 
 	enum sgsn_auth_state	auth_state;
-	int			is_authenticated;
+	enum osmo_sub_auth_type sec_ctx;
 
 	/* the string representation of the current hlr */
 	char 			hlr[GSM_EXTENSION_LENGTH];
@@ -235,6 +235,17 @@
 	struct gprs_subscr	*subscr;
 };
 
+static inline bool sgsn_mm_ctx_is_authenticated(struct sgsn_mm_ctx *ctx)
+{
+	switch (ctx->sec_ctx) {
+	case OSMO_AUTH_TYPE_GSM:
+	case OSMO_AUTH_TYPE_UMTS:
+		return true;
+	default:
+		return false;
+	}
+}
+
 #define LOGMMCTXP(level, mm, fmt, args...) \
 	LOGP(DMM, level, "MM(%s/%08x) " fmt, (mm) ? (mm)->imsi : "---", \
 	     (mm) ? (mm)->p_tmsi : GSM_RESERVED_TMSI, ## args)
diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c
index 642c738..28fba71 100644
--- a/src/gprs/gprs_gmm.c
+++ b/src/gprs/gprs_gmm.c
@@ -662,24 +662,24 @@
 }
 
 /* check if the received authentication response matches */
-static bool check_auth_resp(struct sgsn_mm_ctx *ctx,
-			    bool is_utran,
-			    const struct osmo_auth_vector *vec,
-			    const uint8_t *res, uint8_t res_len)
+static enum osmo_sub_auth_type check_auth_resp(struct sgsn_mm_ctx *ctx,
+					       bool is_utran,
+					       const struct osmo_auth_vector *vec,
+					       const uint8_t *res, uint8_t res_len)
 {
 	const uint8_t *expect_res;
 	uint8_t expect_res_len;
 	enum osmo_sub_auth_type expect_type;
 	const char *expect_str;
 
-	if (!vec)
-		return true; /* really!? */
-
 	/* On UTRAN (3G) we always expect UMTS AKA. On GERAN (2G) we sent AUTN
 	 * and expect UMTS AKA if there is R99 capability and our vector
-	 * supports UMTS AKA, otherwise we expect GSM AKA. */
+	 * supports UMTS AKA, otherwise we expect GSM AKA.
+	 * However, on GERAN, even if we sent a UMTS AKA Authentication Request, the MS may decide to
+	 * instead reply with a GSM AKA SRES response. */
 	if (is_utran
-	    || (mmctx_is_r99(ctx) && (vec->auth_types & OSMO_AUTH_TYPE_UMTS))) {
+	    || (mmctx_is_r99(ctx) && (vec->auth_types & OSMO_AUTH_TYPE_UMTS)
+		&& (res_len > sizeof(vec->sres)))) {
 		expect_type = OSMO_AUTH_TYPE_UMTS;
 		expect_str = "UMTS RES";
 		expect_res = vec->res;
@@ -696,7 +696,7 @@
 			  " not provide the expected auth type:"
 			  " expected %s = 0x%x, auth_types are 0x%x\n",
 			  expect_str, expect_type, vec->auth_types);
-		return false;
+		return OSMO_AUTH_TYPE_NONE;
 	}
 
 	if (!res)
@@ -709,12 +709,12 @@
 		goto auth_mismatch;
 
 	/* Authorized! */
-	return true;
+	return expect_type;
 
 auth_mismatch:
 	LOGMMCTXP(LOGL_ERROR, ctx, "Auth mismatch: expected %s = %s\n",
 		  expect_str, osmo_hexdump_nospc(expect_res, expect_res_len));
-	return false;
+	return OSMO_AUTH_TYPE_NONE;
 }
 
 /* Section 9.4.10: Authentication and Ciphering Response */
@@ -778,14 +778,12 @@
 
 	LOGMMCTXP(LOGL_DEBUG, ctx, "checking auth: received %s = %s\n",
 		  res_name, osmo_hexdump(res, res_len));
-	rc = check_auth_resp(ctx, false, &at->vec, res, res_len);
-	if (!rc) {
+	ctx->sec_ctx = check_auth_resp(ctx, false, &at->vec, res, res_len);
+	if (!sgsn_mm_ctx_is_authenticated(ctx)) {
 		rc = gsm48_tx_gmm_auth_ciph_rej(ctx);
 		mm_ctx_cleanup_free(ctx, "GPRS AUTH AND CIPH REJECT");
 		return rc;
 	}
-
-	ctx->is_authenticated = 1;
 
 	if (ctx->ran_type == MM_CTX_T_UTRAN_Iu)
 		ctx->iu.new_key = 1;
@@ -1026,7 +1024,8 @@
 		return 0;
 	}
 
-	if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && !ctx->is_authenticated) {
+	if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE
+	    && !sgsn_mm_ctx_is_authenticated(ctx)) {
 		struct gsm_auth_tuple *at = &ctx->auth_triplet;
 
 		mmctx_timer_start(ctx, 3360, sgsn->cfg.timers.T3360);
@@ -1034,7 +1033,7 @@
 						  false);
 	}
 
-	if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && ctx->is_authenticated &&
+	if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_mm_ctx_is_authenticated(ctx) &&
 	    ctx->auth_triplet.key_seq != GSM_KEY_SEQ_INVAL) {
 		/* Check again for authorization */
 		sgsn_auth_request(ctx);
@@ -1106,7 +1105,7 @@
 
 void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *ctx)
 {
-	ctx->is_authenticated = 0;
+	ctx->sec_ctx = OSMO_AUTH_TYPE_NONE;
 
 	gsm48_gmm_authorize(ctx);
 }
@@ -1420,7 +1419,7 @@
 		ctx->gb.tlli_new = gprs_tmsi2tlli(ctx->p_tmsi, TLLI_LOCAL);
 
 		/* Inform LLC layer about new TLLI but keep old active */
-		if (ctx->is_authenticated)
+		if (sgsn_mm_ctx_is_authenticated(ctx))
 			gprs_llme_copy_key(ctx, ctx->gb.llme);
 
 		gprs_llgmm_assign(ctx->gb.llme, ctx->gb.tlli, ctx->gb.tlli_new);
diff --git a/src/gprs/sgsn_auth.c b/src/gprs/sgsn_auth.c
index 6fb32b7..694bece 100644
--- a/src/gprs/sgsn_auth.c
+++ b/src/gprs/sgsn_auth.c
@@ -114,7 +114,7 @@
 			return mmctx->auth_state;
 
 		if (sgsn->cfg.require_authentication &&
-		    (!mmctx->is_authenticated ||
+		    (!sgsn_mm_ctx_is_authenticated(mmctx) ||
 		     mmctx->subscr->sgsn_data->auth_triplets_updated))
 			return SGSN_AUTH_AUTHENTICATE;
 
@@ -175,7 +175,7 @@
 
 	OSMO_ASSERT(mmctx->subscr != NULL);
 
-	if (sgsn->cfg.require_authentication && !mmctx->is_authenticated) {
+	if (sgsn->cfg.require_authentication && !sgsn_mm_ctx_is_authenticated(mmctx)) {
 		/* Find next tuple */
 		at = sgsn_auth_get_tuple(mmctx, mmctx->auth_triplet.key_seq);
 
diff --git a/tests/sgsn/sgsn_test.c b/tests/sgsn/sgsn_test.c
index df4df3b..0e5267b 100644
--- a/tests/sgsn/sgsn_test.c
+++ b/tests/sgsn/sgsn_test.c
@@ -1132,7 +1132,7 @@
 {
 	/* Fake an authentication */
 	OSMO_ASSERT(mmctx->subscr);
-	mmctx->is_authenticated = 1;
+	mmctx->sec_ctx = OSMO_AUTH_TYPE_GSM;
 	gprs_subscr_update_auth_info(mmctx->subscr);
 
 	return 0;

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I36807bad3bc55c0030d4f09cb2c369714f24bec7
Gerrit-PatchSet: 1
Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list