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/.
Harald Welte gerrit-no-reply at lists.osmocom.orgHarald Welte has submitted this change and it was merged. Change subject: msc: Cipher mode negotiation test ...................................................................... msc: Cipher mode negotiation test This adds a series of test cases that test various combinations of A5/0, A5/1, A5/2 and A5/3 on both phone as well as network config side. Change-Id: I552fa4a23b7b65613a69b1a822e28e7dea401102 --- M msc/BSC_ConnectionHandler.ttcn M msc/MSC_Tests.ttcn 2 files changed, 213 insertions(+), 8 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn index a801e51..4f50b70 100644 --- a/msc/BSC_ConnectionHandler.ttcn +++ b/msc/BSC_ConnectionHandler.ttcn @@ -55,11 +55,57 @@ hexstring imsi, hexstring msisdn, OCT4 tmsi optional, + MobileStationClassmark1_V cm1, BSSMAP_IE_ClassmarkInformationType2 cm2, BSSMAP_IE_ClassmarkInformationType3 cm3 optional, AuthVector vec optional, BSC_ConnHdlrNetworkPars net }; + +/* get a one-octet bitmaks of supported algorithms based on Classmark information */ +function f_alg_mask_from_cm(BSSMAP_IE_ClassmarkInformationType2 cm2) return OCT1 { + var BIT8 res := '00000001'B; /* A5/0 always supported */ + + if (cm2.a5_1 == '0'B) { + res := res or4b '00000010'B; + } + if (cm2.classmarkInformationType2_oct5.a5_2 == '1'B ) { + res := res or4b '00000100'B; + } + if (cm2.classmarkInformationType2_oct5.a5_3 == '1'B) { + res := res or4b '00001000'B; + } + /* TODO: CM3 for A5/4 and beyond */ + return bit2oct(res); +} + +/* determine the best algorithm available within the bit-mask */ +function f_best_alg_from_mask(OCT1 alg_in) return OCT1 { + var BIT8 alg := oct2bit(alg_in); + var BIT8 ordered_algs[8] := { + '10000000'B, '01000000'B, '00100000'B, '00010000'B, + '00001000'B, /* A5/3 */ + '00000010'B, /* A5/1 */ + '00000100'B, /* A5/2 */ + '00000001'B /* A5/0 */ } + for (var integer i := 0; i < sizeof(ordered_algs); i := i+1) { + if (alg and4b ordered_algs[i] != '00000000'B) { + return bit2oct(ordered_algs[i]); + } + } + return '00'O; +} + +/* return an integer like '1' for A5/1 based on a mask (with only one bit set */ +function f_alg_from_mask(OCT1 mask_in) return integer { + var BIT8 mask := oct2bit(mask_in); + for (var integer i := 0; i < 8; i := i+1) { + if (mask and4b ('00000001'B << i) != '00000000'B) { + return i; + } + } + return -1; +} /* altstep for the global guard timer */ private altstep as_Tguard() runs on BSC_ConnHdlr { @@ -172,26 +218,26 @@ /* build a PDU_ML3_MS_NW containing a Location Update by IMSI */ -function f_build_lu_imsi(hexstring imsi) return PDU_ML3_MS_NW +function f_build_lu_imsi(hexstring imsi) runs on BSC_ConnHdlr return PDU_ML3_MS_NW { var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(imsi)); return f_build_lu(mi); } -function f_build_lu_imei(hexstring imei) return PDU_ML3_MS_NW +function f_build_lu_imei(hexstring imei) runs on BSC_ConnHdlr return PDU_ML3_MS_NW { var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(imei)); return f_build_lu(mi); } -function f_build_lu_tmsi(OCT4 tmsi) return PDU_ML3_MS_NW +function f_build_lu_tmsi(OCT4 tmsi) runs on BSC_ConnHdlr return PDU_ML3_MS_NW { var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV(tmsi)); return f_build_lu(mi); } -private function f_build_lu(MobileIdentityLV mi) return PDU_ML3_MS_NW +private function f_build_lu(MobileIdentityLV mi) runs on BSC_ConnHdlr return PDU_ML3_MS_NW { var LocationAreaIdentification_V old_lai := { '62F220'O, '9999'O }; var PDU_ML3_MS_NW l3_info := valueof(ts_ML3_MO_LU_Req(valueof(ts_ML3_IE_LuType_Attach), - old_lai, mi, valueof(ts_CM1))); + old_lai, mi, g_pars.cm1)); return l3_info; } @@ -213,7 +259,7 @@ } -function f_mm_common() runs on BSC_ConnHdlr +function f_mm_auth() runs on BSC_ConnHdlr { if (g_pars.net.expect_auth) { g_pars.vec := f_gen_auth_vec_2g(); @@ -226,10 +272,26 @@ BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(g_pars.vec.rand))); BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G(g_pars.vec.sres))); } +} +function f_mm_common() runs on BSC_ConnHdlr +{ + f_mm_auth(); if (g_pars.net.expect_ciph) { - BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)); - BSSAP.send(ts_BSSMAP_CipherModeCompl('02'O)); + var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2); + var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net; + alt { + [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) { + var OCT1 a5_chosen := f_best_alg_from_mask(a5_intersect); + var integer a5_nr := f_alg_from_mask(a5_chosen); + BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(a5_nr+1, 1))); + } + [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) { + setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd"); + self.stop; + } + } + /* FIXME: Send the best available algorithm */ } } diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn index 90f308f..f91ff38 100644 --- a/msc/MSC_Tests.ttcn +++ b/msc/MSC_Tests.ttcn @@ -368,6 +368,7 @@ imsi := f_gen_imsi(imsi_suffix), msisdn := f_gen_msisdn(imsi_suffix), tmsi := omit, + cm1 := valueof(ts_CM1), cm2 := valueof(ts_CM2_default), cm3 := omit, vec := omit, @@ -1438,6 +1439,143 @@ vc_conn.done; } +/* A5/1 only permitted on network side, and MS capable to do it */ +private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr { + pars.net.expect_auth := true; + pars.net.expect_ciph := true; + pars.net.kc_support := '02'O; /* A5/1 only */ + f_init_handler(pars); + f_perform_lu(true); +} +testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT { + var BSC_ConnHdlr vc_conn; + f_init(); + f_vty_config(MSCVTY, "network", "authentication required"); + f_vty_config(MSCVTY, "network", "encryption a5 1"); + + vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), testcasename(), 32); + vc_conn.done; +} + +/* A5/3 only permitted on network side, and MS capable to do it */ +private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr { + pars.net.expect_auth := true; + pars.net.expect_ciph := true; + pars.net.kc_support := '08'O; /* A5/3 only */ + f_init_handler(pars); + f_perform_lu(true); +} +testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT { + var BSC_ConnHdlr vc_conn; + f_init(); + f_vty_config(MSCVTY, "network", "authentication required"); + f_vty_config(MSCVTY, "network", "encryption a5 3"); + + vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), testcasename(), 33); + vc_conn.done; +} + +/* A5/3 only permitted on network side, and MS with only A5/1 support */ +private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr { + pars.net.expect_auth := true; + pars.net.expect_ciph := true; + pars.net.kc_support := '08'O; /* A5/3 only */ + pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B; + f_init_handler(pars, 15.0); + + /* cannot use f_perform_lu() as we expect a reject */ + var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi); + f_create_gsup_expect(hex2str(g_pars.imsi)); + f_bssap_compl_l3(l3_lu); + BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3)); + f_mm_auth(); + alt { + [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { } + [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) { + setverdict(fail, "CipherModeCommand despite no A5 intersection"); + self.stop; + } + [] BSSAP.receive { + setverdict(inconc, "Unknown/unexpected BSSAP received"); + self.stop; + } + } + setverdict(pass); +} +testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT { + var BSC_ConnHdlr vc_conn; + f_init(); + f_vty_config(MSCVTY, "network", "authentication required"); + f_vty_config(MSCVTY, "network", "encryption a5 3"); + + vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), testcasename(), 34); + vc_conn.done; +} + +/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */ +private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr { + pars.net.expect_auth := true; + pars.net.expect_ciph := true; + pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */ + pars.cm1.a5_1 := '1'B; + pars.cm2.a5_1 := '1'B; + pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B; + pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B; + f_init_handler(pars, 15.0); + + /* cannot use f_perform_lu() as we expect a reject */ + var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi); + f_create_gsup_expect(hex2str(g_pars.imsi)); + f_bssap_compl_l3(l3_lu); + BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3)); + f_mm_auth(); + alt { + [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { } + [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) { + setverdict(fail, "CipherModeCommand despite no A5 intersection"); + self.stop; + } + [] BSSAP.receive { + setverdict(inconc, "Unknown/unexpected BSSAP received"); + self.stop; + } + } + setverdict(pass); +} +testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT { + var BSC_ConnHdlr vc_conn; + f_init(); + f_vty_config(MSCVTY, "network", "authentication required"); + f_vty_config(MSCVTY, "network", "encryption a5 1 3"); + + vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), testcasename(), 35); + vc_conn.done; +} + +/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */ +private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr { + pars.net.expect_auth := true; + pars.net.expect_ciph := true; + pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */ + pars.cm1.a5_1 := '1'B; + pars.cm2.a5_1 := '1'B; + pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B; + pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B; + f_init_handler(pars, 15.0); + f_perform_lu(true); +} +testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT { + var BSC_ConnHdlr vc_conn; + f_init(); + f_vty_config(MSCVTY, "network", "authentication required"); + f_vty_config(MSCVTY, "network", "encryption a5 0 1 3"); + + vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), testcasename(), 36); + vc_conn.done; +} + + + /* TODO: @@ -1487,6 +1625,11 @@ execute( TC_mt_crcx_ran_reject() ); execute( TC_mt_t310() ); execute( TC_gsup_cancel() ); + execute( TC_lu_imsi_auth_tmsi_encr_1_13() ); + execute( TC_lu_imsi_auth_tmsi_encr_3_13() ); + execute( TC_lu_imsi_auth_tmsi_encr_3_1() ); + execute( TC_lu_imsi_auth_tmsi_encr_13_2() ); + execute( TC_lu_imsi_auth_tmsi_encr_013_2() ); } -- To view, visit https://gerrit.osmocom.org/6145 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I552fa4a23b7b65613a69b1a822e28e7dea401102 Gerrit-PatchSet: 1 Gerrit-Project: osmo-ttcn3-hacks Gerrit-Branch: master Gerrit-Owner: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder