pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/33053 )
Change subject: gmm: Tx Auth & Ciph Failure ......................................................................
gmm: Tx Auth & Ciph Failure
Change-Id: I3ebb3dba20010e57f29dd5b8bbec457c2b08a8e1 --- M include/osmocom/gprs/gmm/gmm_pdu.h M include/osmocom/gprs/gmm/gmm_private.h M src/gmm/gmm.c M src/gmm/gmm_pdu.c M src/gmm/gmm_prim.c 5 files changed, 77 insertions(+), 3 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_pdu.h b/include/osmocom/gprs/gmm/gmm_pdu.h index 18a181c..541cb48 100644 --- a/include/osmocom/gprs/gmm/gmm_pdu.h +++ b/include/osmocom/gprs/gmm/gmm_pdu.h @@ -3,6 +3,7 @@
#include <osmocom/core/msgb.h> #include <osmocom/gsm/tlv.h> +#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
struct gprs_gmm_entity; enum gprs_gmm_upd_type; @@ -39,6 +40,9 @@ enum osmo_gprs_gmm_detach_poweroff_type poweroff_type, struct msgb *msg);
+int gprs_gmm_build_auth_ciph_fail(struct gprs_gmm_entity *gmme, + struct msgb *msg, enum gsm48_gmm_cause cause); + int gprs_gmm_build_rau_req(struct gprs_gmm_entity *gmme, enum gprs_gmm_upd_type rau_type, struct msgb *msg); diff --git a/include/osmocom/gprs/gmm/gmm_private.h b/include/osmocom/gprs/gmm/gmm_private.h index ac64ea1..0308d1e 100644 --- a/include/osmocom/gprs/gmm/gmm_private.h +++ b/include/osmocom/gprs/gmm/gmm_private.h @@ -12,6 +12,7 @@ #include <osmocom/core/endian.h> #include <osmocom/core/tdef.h> #include <osmocom/gsm/protocol/gsm_23_003.h> +#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gprs/llc/llc_prim.h> #include <osmocom/gprs/gmm/gmm.h> @@ -132,6 +133,7 @@ enum osmo_gprs_gmm_detach_poweroff_type poweroff_type); int gprs_gmm_tx_rau_req(struct gprs_gmm_entity *gmme, enum gprs_gmm_upd_type rau_type); int gprs_gmm_tx_auth_ciph_resp(const struct gprs_gmm_entity *gmme, const uint8_t *sres); +int gprs_gmm_tx_auth_ciph_fail(struct gprs_gmm_entity *gmme, enum gsm48_gmm_cause cause);
int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted, uint8_t cause); int gprs_gmm_submit_gmmsm_establish_cnf(struct gprs_gmm_entity *gmme, bool accepted, uint8_t cause); diff --git a/src/gmm/gmm.c b/src/gmm/gmm.c index 55b5d66..092a56c 100644 --- a/src/gmm/gmm.c +++ b/src/gmm/gmm.c @@ -704,6 +704,42 @@ return rc; }
+/* Tx GMM Authentication and Ciphering Failure, 9.4.10a */ +int gprs_gmm_tx_auth_ciph_fail(struct gprs_gmm_entity *gmme, enum gsm48_gmm_cause cause) +{ + struct osmo_gprs_llc_prim *llc_prim; + int rc; + struct msgb *msg; + + LOGGMME(gmme, LOGL_INFO, "Tx GMM AUTHENTICATION AND CIPHERING FAILURE cause=0x%02x '%s'\n", + cause, get_value_string(gsm48_gmm_cause_names, cause)); + + llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req( + gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); + msg = llc_prim->oph.msg; + msg->l3h = msg->tail; + rc = gprs_gmm_build_auth_ciph_fail(gmme, msg, cause); + if (rc < 0) { + msgb_free(msg); + return -EBADMSG; + } + llc_prim->ll.l3_pdu = msg->l3h; + llc_prim->ll.l3_pdu_len = msgb_l3len(msg); + /* TODO: + llc_prim->ll.qos_params.*; + llc_prim->ll.radio_prio; + llc_prim->ll.apply_gea; + llc_prim->ll.apply_gia; + */ + + /* 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; + return rc; +} + /* Tx GMM Routing area update request, 9.4.14 */ int gprs_gmm_tx_rau_req(struct gprs_gmm_entity *gmme, enum gprs_gmm_upd_type rau_type) @@ -1166,6 +1202,7 @@
if (len < sizeof(*gh) + sizeof(*acreq)) { LOGGMME(gmme, LOGL_ERROR, "Rx GMM AUTHENTICATION AND CIPHERING REQUEST with wrong size %u\n", len); + gprs_gmm_tx_auth_ciph_fail(gmme, GMM_CAUSE_SEM_INCORR_MSG); return -EINVAL; }
@@ -1177,6 +1214,7 @@ len - (sizeof(*gh) + sizeof(*acreq))); if (rc < 0) { LOGGMME(gmme, LOGL_ERROR, "Rx GMM AUTHENTICATION AND CIPHERING REQUEST: failed to parse TLVs %d\n", rc); + gprs_gmm_tx_auth_ciph_fail(gmme, GMM_CAUSE_COND_IE_ERR); return -EINVAL; } if (TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_RAND)) { @@ -1206,14 +1244,17 @@ if (rand) { /* SIM AUTH needed. Answer GMM req asynchronously in GMMREG-SIM_AUTH.rsp: */ rc = gprs_gmm_submit_gmmreg_sim_auth_ind(gmme); - /* TODO: if rc < 0, transmit AUTHENTICATION AND CIPHERING FAILURE (9.4.10a) */ + if (rc < 0) { + gprs_gmm_tx_auth_ciph_fail(gmme, GMM_CAUSE_GSM_AUTH_UNACCEPT); + return rc; + } } else { /* Submit LLGMM-ASSIGN-REQ as per TS 24.007 Annex C.1 */ rc = gprs_gmm_submit_llgmm_assing_req(gmme); if (rc < 0) { - /* TODO: if rc < 0, transmit AUTHENTICATION AND CIPHERING FAILURE (9.4.10a) */ /* invalidate active reference: */ gmme->auth_ciph.req.ac_ref_nr = 0xff; + gprs_gmm_tx_auth_ciph_fail(gmme, GMM_CAUSE_MSG_INCOMP_P_STATE); return rc; } rc = gprs_gmm_tx_auth_ciph_resp(gmme, NULL); diff --git a/src/gmm/gmm_pdu.c b/src/gmm/gmm_pdu.c index 5ff7a20..7c83ac5 100644 --- a/src/gmm/gmm_pdu.c +++ b/src/gmm/gmm_pdu.c @@ -295,6 +295,24 @@ return 0; }
+/* 9.4.10a Authentication and Ciphering Failure */ +int gprs_gmm_build_auth_ciph_fail(struct gprs_gmm_entity *gmme, struct msgb *msg, + enum gsm48_gmm_cause cause) +{ + struct gsm48_hdr *gh; + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + gh->proto_discr = GSM48_PDISC_MM_GPRS; + gh->msg_type = GSM48_MT_GMM_PTMSI_REALL_COMPL; + + /* 10.5.5.14 Cause */ + msgb_put_u8(msg, (uint8_t)cause); + + /* TODO: 10.5.3.2.2 Authentication Failure parameter */ + return 0; +} + + /* Chapter 9.4.14: Routing area update request */ int gprs_gmm_build_rau_req(struct gprs_gmm_entity *gmme, enum gprs_gmm_upd_type rau_type, diff --git a/src/gmm/gmm_prim.c b/src/gmm/gmm_prim.c index bea8341..2122d76 100644 --- a/src/gmm/gmm_prim.c +++ b/src/gmm/gmm_prim.c @@ -447,9 +447,9 @@
rc = gprs_gmm_submit_llgmm_assing_req(gmme); if (rc < 0) { - /* TODO: if rc < 0, transmit AUTHENTICATION AND CIPHERING FAILURE (9.4.10a) */ /* invalidate active reference: */ gmme->auth_ciph.req.ac_ref_nr = 0xff; + gprs_gmm_tx_auth_ciph_fail(gmme, GMM_CAUSE_MSG_INCOMP_P_STATE); return rc; }