diff --git a/src/libvlr/vlr_auth_fsm.c b/src/libvlr/vlr_auth_fsm.c index 51e22c9dc..0d0df1172 100644 --- a/src/libvlr/vlr_auth_fsm.c +++ b/src/libvlr/vlr_auth_fsm.c @@ -136,34 +136,57 @@ static bool check_auth_resp(struct vlr_subscr *vsub, bool is_r99, struct gsm_auth_tuple *at = vsub->last_tuple; struct osmo_auth_vector *vec = &at->vec; bool check_umts; + bool res_is_umts_aka; OSMO_ASSERT(at); LOGVSUBP(LOGL_DEBUG, vsub, "received res: %s\n", osmo_hexdump(res, res_len)); /* RES must be present and at least 32bit */ - if (!res || res_len < sizeof(vec->sres)) { - LOGVSUBP(LOGL_NOTICE, vsub, "AUTH RES missing or too short " - "(%u)\n", res_len); + if (!res || !res_len) { + LOGVSUBP(LOGL_NOTICE, vsub, "AUTH SRES/RES missing\n"); goto out_false; } - check_umts = false; - if (is_r99 && (vec->auth_types & OSMO_AUTH_TYPE_UMTS)) { - check_umts = true; - /* We have a R99 capable UE and have a UMTS AKA capable USIM. - * However, the ME may still choose to only perform GSM AKA, as - * long as the bearer is GERAN */ - if (res_len != vec->res_len) { - if (is_utran) { - LOGVSUBP(LOGL_NOTICE, vsub, - "AUTH via UTRAN but " - "res_len(%u) != vec->res_len(%u)\n", - res_len, vec->res_len); - goto out_false; - } - check_umts = false; - } + /* We're deciding the UMTS AKA-ness of the response by the RES size. So let's make sure we can't + * mix them up by size. On UTRAN, we expect full length RES always, no way to mix up there. */ + if (!is_utran && vec->res_len == sizeof(vec->sres)) + LOGVSUBP(LOGL_ERROR, vsub, "Unforeseen situation: UMTS AKA's RES length" + " equals the size of SRES: %u -- this code wants to differentiate" + " the two by their size, which won't work properly now.\n", vec->res_len); + + /* RES must be either vec->res_len (UMTS AKA) or sizeof(sres) (GSM AKA) */ + if (res_len == vec->res_len) + res_is_umts_aka = true; + else if (res_len == sizeof(vec->sres)) + res_is_umts_aka = false; + else { + if (is_utran) + LOGVSUBP(LOGL_NOTICE, vsub, "AUTH RES has invalid length: %u." + " Expected %u (UMTS AKA)\n", + res_len, vec->res_len); + else + LOGVSUBP(LOGL_NOTICE, vsub, "AUTH SRES/RES has invalid length: %u." + " Expected either %zu (GSM AKA) or %u (UMTS AKA)\n", + res_len, sizeof(vec->sres), vec->res_len); + goto out_false; + } + + check_umts = (is_r99 + && (vec->auth_types & OSMO_AUTH_TYPE_UMTS) + && res_is_umts_aka); + + /* Even on an R99 capable MS with a UMTS AKA capable USIM, + * the MS may still choose to only perform GSM AKA, as + * long as the bearer is GERAN -- never on UTRAN: */ + if (is_utran && !check_umts) { + LOGVSUBP(LOGL_ERROR, vsub, + "AUTH via UTRAN, cannot allow GSM AKA" + " (MS is %sR99 capable, vec has %sUMTS AKA tokens, res_len=%u is %s)\n", + is_r99 ? "" : "NOT ", + (vec->auth_types & OSMO_AUTH_TYPE_UMTS) ? "" : "NO ", + res_len, (res_len == vec->res_len)? "valid" : "INVALID on UTRAN"); + goto out_false; } if (check_umts) { diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.err b/tests/msc_vlr/msc_vlr_test_gsm_authen.err index a454e2fb5..590b31932 100644 --- a/tests/msc_vlr/msc_vlr_test_gsm_authen.err +++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.err @@ -2074,7 +2074,7 @@ DMM IMSI:901700000004620: MM AUTHENTICATION RESPONSE: invalid: parsing GSM AKA A DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = ) DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI:901700000004620) received res: -DVLR SUBSCR(IMSI:901700000004620) AUTH RES missing or too short (0) +DVLR SUBSCR(IMSI:901700000004620) AUTH SRES/RES missing DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_AUTH_FAILED DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR GSUP tx: 0b010809710000004026f0 diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.err b/tests/msc_vlr/msc_vlr_test_umts_authen.err index 77a056fa7..5573c02cf 100644 --- a/tests/msc_vlr/msc_vlr_test_umts_authen.err +++ b/tests/msc_vlr/msc_vlr_test_umts_authen.err @@ -1447,7 +1447,7 @@ DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI:901700000010650) received res: e2 29 c1 9e 79 1f 2e -DVLR SUBSCR(IMSI:901700000010650) GSM AUTH failure: mismatching sres (expected sres=9b 36 ef df ) +DVLR SUBSCR(IMSI:901700000010650) AUTH SRES/RES has invalid length: 7. Expected either 4 (GSM AKA) or 8 (UMTS AKA) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_AUTH_FAILED DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR GSUP tx: 0b010809710000000156f0 @@ -1541,7 +1541,7 @@ DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI:901700000010650) received res: e2 29 c1 9e 79 1f 2e -DVLR SUBSCR(IMSI:901700000010650) AUTH via UTRAN but res_len(7) != vec->res_len(8) +DVLR SUBSCR(IMSI:901700000010650) AUTH RES has invalid length: 7. Expected 8 (UMTS AKA) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_AUTH_FAILED DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR GSUP tx: 0b010809710000000156f0 @@ -1635,7 +1635,7 @@ DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e4123) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI:901700000010650) received res: e2 29 c1 9e 79 1f 2e 41 23 -DVLR SUBSCR(IMSI:901700000010650) GSM AUTH failure: mismatching sres (expected sres=9b 36 ef df ) +DVLR SUBSCR(IMSI:901700000010650) AUTH SRES/RES has invalid length: 9. Expected either 4 (GSM AKA) or 8 (UMTS AKA) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_AUTH_FAILED DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR GSUP tx: 0b010809710000000156f0 @@ -1729,7 +1729,7 @@ DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e4123) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI:901700000010650) received res: e2 29 c1 9e 79 1f 2e 41 23 -DVLR SUBSCR(IMSI:901700000010650) AUTH via UTRAN but res_len(9) != vec->res_len(8) +DVLR SUBSCR(IMSI:901700000010650) AUTH RES has invalid length: 9. Expected 8 (UMTS AKA) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_AUTH_FAILED DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR GSUP tx: 0b010809710000000156f0 @@ -1917,7 +1917,7 @@ DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) DMM IMSI:901700000010650: MM GSM AUTHENTICATION RESPONSE (sres = e229c19e) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI:901700000010650) received res: e2 29 c1 9e -DVLR SUBSCR(IMSI:901700000010650) AUTH via UTRAN but res_len(4) != vec->res_len(8) +DVLR SUBSCR(IMSI:901700000010650) AUTH via UTRAN, cannot allow GSM AKA (MS is R99 capable, vec has UMTS AKA tokens, res_len=4 is INVALID on UTRAN) DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_AUTH_FAILED DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR GSUP tx: 0b010809710000000156f0