pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/33054 )
Change subject: gmm: Initial implementation of T3166, rx Auth & Ciph Reject ......................................................................
gmm: Initial implementation of T3166, rx Auth & Ciph Reject
As specified in 3GPP TS 24.008 Table 11.3/3.
Change-Id: I2c24b968e90cf5ec71fa8a777ec57b407eec015f --- M include/osmocom/gprs/gmm/gmm_private.h M src/gmm/gmm.c M src/gmm/gmm_ms_fsm.c M src/gmm/gmm_prim.c M tests/gmm/gmm_prim_test.err 5 files changed, 85 insertions(+), 0 deletions(-)
Approvals: laforge: Looks good to me, but someone else must approve Jenkins Builder: Verified osmith: Looks good to me, but someone else must approve pespin: Looks good to me, approved
diff --git a/include/osmocom/gprs/gmm/gmm_private.h b/include/osmocom/gprs/gmm/gmm_private.h index 0308d1e..5a29600 100644 --- a/include/osmocom/gprs/gmm/gmm_private.h +++ b/include/osmocom/gprs/gmm/gmm_private.h @@ -89,6 +89,7 @@ unsigned long t3314_assigned_sec; /* value assigned by the network */ struct osmo_timer_list t3312; /* periodic RAU, in seconds */ unsigned long t3312_assigned_sec; /* value assigned by the network */ + struct osmo_timer_list t3316; /* Delete stored RAND & SRES */
/* network name */ char name_long[32]; @@ -124,6 +125,8 @@ bool gprs_gmm_gmme_ready_timer_running(const struct gprs_gmm_entity *gmme); void gprs_gmm_gmme_t3312_start(struct gprs_gmm_entity *gmme); void gprs_gmm_gmme_t3312_stop(struct gprs_gmm_entity *gmme); +void gprs_gmm_gmme_t3316_start(struct gprs_gmm_entity *gmme); +void gprs_gmm_gmme_t3316_stop(struct gprs_gmm_entity *gmme); int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len); int gprs_gmm_tx_att_req(struct gprs_gmm_entity *gmme, enum osmo_gprs_gmm_attach_type attach_type, diff --git a/src/gmm/gmm.c b/src/gmm/gmm.c index 092a56c..1dcee79 100644 --- a/src/gmm/gmm.c +++ b/src/gmm/gmm.c @@ -88,6 +88,7 @@
static void t3314_ready_timer_cb(void *data); static void t3312_periodic_rau_timer_cb(void *data); +static void t3316_delete_rand_sres_cb(void *data);
static void gprs_gmm_ctx_free(void) { @@ -186,6 +187,7 @@
osmo_timer_setup(&gmme->t3314, t3314_ready_timer_cb, gmme); osmo_timer_setup(&gmme->t3312, t3312_periodic_rau_timer_cb, gmme); + osmo_timer_setup(&gmme->t3316, t3316_delete_rand_sres_cb, gmme);
llist_add(&gmme->list, &g_gmm_ctx->gmme_list);
@@ -202,6 +204,8 @@ osmo_timer_del(&gmme->t3314); if (osmo_timer_pending(&gmme->t3312)) osmo_timer_del(&gmme->t3312); + if (osmo_timer_pending(&gmme->t3316)) + osmo_timer_del(&gmme->t3316); gprs_gmm_ms_fsm_ctx_release(&gmme->ms_fsm); llist_del(&gmme->list); talloc_free(gmme); @@ -389,6 +393,37 @@
}
+/* T3316 (Delete stored RAND & SRES) is started: */ +void gprs_gmm_gmme_t3316_start(struct gprs_gmm_entity *gmme) +{ + unsigned long timeout_sec = osmo_tdef_get(g_gmm_ctx->T_defs, 3316, OSMO_TDEF_S, -1); + + if (timeout_sec == 0) + return; + LOGGMME(gmme, LOGL_INFO, "T3316 started (expires in %lu seconds)\n", timeout_sec); + osmo_timer_schedule(&gmme->t3316, timeout_sec, 0); +} + +/* T3316 (Delete stored RAND & SRES) is stopped: */ +void gprs_gmm_gmme_t3316_stop(struct gprs_gmm_entity *gmme) +{ + if (!osmo_timer_pending(&gmme->t3316)) + return; + + LOGGMME(gmme, LOGL_INFO, "T3316 stopped\n"); + osmo_timer_del(&gmme->t3316); +} + +/* T3312 (Delete stored RAND & SRES) timer expiration: */ +static void t3316_delete_rand_sres_cb(void *data) +{ + struct gprs_gmm_entity *gmme = (struct gprs_gmm_entity *)data; + LOGGMME(gmme, LOGL_INFO, "T3316 (Delete stored RAND & SRES timer) expired\n"); + /* invalidate active reference: */ + gmme->auth_ciph.req.ac_ref_nr = 0xff; + /* Nothing more to do yet, since we really never store RAND & SRES so far? */ +} + int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted, uint8_t cause) { struct osmo_gprs_gmm_prim *gmm_prim_tx; @@ -732,8 +767,14 @@ llc_prim->ll.apply_gia; */
+ /* TS 24.008 4.7.7.5.1: "If the MS returns an AUTHENTICATION AND CIPHERING FAILURE + * message to the network, the MS shall delete any previously stored RAND and RES + * and shall stop timer T3316, if running." + */ + gprs_gmm_gmme_t3316_stop(gmme); /* invalidate active reference: */ gmme->auth_ciph.req.ac_ref_nr = 0xff; + rc = gprs_gmm_prim_call_llc_down_cb(llc_prim); if (rc < 0) return rc; @@ -1264,6 +1305,19 @@ return rc; }
+/* Rx GMM Authentication and ciphering reject, 9.4.11 */ +static int gprs_gmm_rx_auth_ciph_rej(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len) +{ + int rc; + uint8_t cause; + + LOGGMME(gmme, LOGL_NOTICE, "Rx GMM AUTHENTICATION AND CIPHERING REJECT\n"); + + cause = GMM_CAUSE_GSM_AUTH_UNACCEPT; + rc = osmo_fsm_inst_dispatch(gmme->ms_fsm.fi, GPRS_GMM_MS_EV_ATTACH_REJECTED, &cause); + return rc; +} + /* Rx GMM Status, 9.4.18 */ static int gprs_gmm_rx_status(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len) { @@ -1335,6 +1389,9 @@ case GSM48_MT_GMM_AUTH_CIPH_REQ: rc = gprs_gmm_rx_auth_ciph_req(gmme, gh, len); break; + case GSM48_MT_GMM_AUTH_CIPH_REJ: + rc = gprs_gmm_rx_auth_ciph_rej(gmme, gh, len); + break; case GSM48_MT_GMM_STATUS: rc = gprs_gmm_rx_status(gmme, gh, len); break; diff --git a/src/gmm/gmm_ms_fsm.c b/src/gmm/gmm_ms_fsm.c index a344494..e5a7002 100644 --- a/src/gmm/gmm_ms_fsm.c +++ b/src/gmm/gmm_ms_fsm.c @@ -72,6 +72,12 @@ return gprs_gmm_tx_rau_req(ctx->gmme, ctx->rau.type); }
+static void st_gmm_ms_null_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gprs_gmm_ms_fsm_ctx *ctx = (struct gprs_gmm_ms_fsm_ctx *)fi->priv; + gprs_gmm_gmme_t3316_stop(ctx->gmme); +} + static void st_gmm_ms_null(struct osmo_fsm_inst *fi, uint32_t event, void *data) { switch (event) { @@ -89,6 +95,7 @@
memset(&ctx->attach, 0, sizeof(ctx->attach)); gprs_gmm_gmme_t3312_stop(ctx->gmme); + gprs_gmm_gmme_t3316_stop(ctx->gmme);
/* TS 24.007 9.5.1.4: informs SM layerthat the MS has been GPRS detached, e.g. by timer expiry */ if (prev_state != GPRS_GMM_MS_ST_NULL) @@ -241,6 +248,7 @@ //mm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_DEREGISTERED_INITIATED); break; case GPRS_GMM_MS_EV_RAU_ACCEPTED: + gprs_gmm_gmme_t3316_stop(ctx->gmme); /* TS 24.007 C.15: submit LLGM-RESUME-REQ */ llc_prim_tx = osmo_gprs_llc_prim_alloc_llgmm_resume_req(ctx->gmme->tlli); OSMO_ASSERT(llc_prim_tx); @@ -284,6 +292,7 @@ .out_state_mask = X(GPRS_GMM_MS_ST_DEREGISTERED), .name = "Null", + .onenter = st_gmm_ms_null_on_enter, .action = st_gmm_ms_null, }, [GPRS_GMM_MS_ST_DEREGISTERED] = { diff --git a/src/gmm/gmm_prim.c b/src/gmm/gmm_prim.c index 2122d76..5a35ef2 100644 --- a/src/gmm/gmm_prim.c +++ b/src/gmm/gmm_prim.c @@ -445,6 +445,8 @@ /* Copy over Kc: */ memcpy(gmme->auth_ciph.kc, gmm_prim->gmmreg.sim_auth_rsp.kc, sizeof(gmme->auth_ciph.kc));
+ gprs_gmm_gmme_t3316_start(gmme); + rc = gprs_gmm_submit_llgmm_assing_req(gmme); if (rc < 0) { /* invalidate active reference: */ diff --git a/tests/gmm/gmm_prim_test.err b/tests/gmm/gmm_prim_test.err index 64af93b..fa670cf 100644 --- a/tests/gmm/gmm_prim_test.err +++ b/tests/gmm/gmm_prim_test.err @@ -13,6 +13,7 @@ DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM AUTHENTICATION AND CIPHERING REQUEST DLGLOBAL INFO Rx from upper layers: GMMREG-SIM_AUTH.response +DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) T3316 started (expires in 30 seconds) DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication @@ -24,6 +25,7 @@ DLGLOBAL INFO GMM_MS{RegisteredInitiated}: state_chg to Registered DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer expired DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) T3312 started (expires in 600 seconds) +DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) T3316 (Delete stored RAND & SRES timer) expired DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) T3312 Periodic RAU timer expired DLGLOBAL INFO GMM_MS{Registered}: Received Event RAU_REQUESTED DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM RAU REQUEST @@ -66,6 +68,7 @@ DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM AUTHENTICATION AND CIPHERING REQUEST DLGLOBAL INFO Rx from upper layers: GMMREG-SIM_AUTH.response +DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) T3316 started (expires in 30 seconds) DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication