summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-03-04 01:26:14 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-03-04 01:26:14 +0100
commit74ef12b345368119812266f6d561b0e9375148e4 (patch)
treec62b0cfa15361c5d87172d28c3977db6512b918c
parentb3742cab88d2fe2df293359eea9e0bdadfd82cab (diff)
implement utran security mode with vlr
-rw-r--r--openbsc/include/openbsc/vlr.h2
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c28
-rw-r--r--openbsc/src/libvlr/vlr.c3
-rw-r--r--openbsc/src/osmo-msc/iucs_ranap.c16
-rw-r--r--openbsc/tests/msc_vlr/msc_vlr_test_umts_authen.c23
-rw-r--r--openbsc/tests/msc_vlr/msc_vlr_tests.c36
-rw-r--r--openbsc/tests/msc_vlr/msc_vlr_tests.h6
7 files changed, 84 insertions, 30 deletions
diff --git a/openbsc/include/openbsc/vlr.h b/openbsc/include/openbsc/vlr.h
index 4a76fe1..8c84868 100644
--- a/openbsc/include/openbsc/vlr.h
+++ b/openbsc/include/openbsc/vlr.h
@@ -191,7 +191,7 @@ struct vlr_ops {
int (*set_ciph_mode)(void *msc_conn_ref, enum vlr_ciph ciph_mode,
bool retrieve_imeisv);
- /* Common Id is transmitted when auth+ciph is complete on UTRAN */
+ /* UTRAN: send Common Id (when auth+ciph are complete) */
int (*tx_common_id)(void *msc_conn_ref);
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 4eac312..aa9ad1d 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -265,12 +265,17 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn,
len = gsm48_generate_mid_from_imsi(mi, conn->vsub->imsi);
mid = msgb_put(msg, len);
memcpy(mid, mi, len);
+ DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT\n",
+ vlr_subscr_name(conn->vsub));
} else {
/* Include the TMSI, which means that the MS will send a
* TMSI REALLOCATION COMPLETE, and we should wait for
* that until T3250 expiration */
mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
gsm48_generate_mid_from_tmsi(mid, send_tmsi);
+ DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT (TMSI = 0x%08x)\n",
+ vlr_subscr_name(conn->vsub),
+ send_tmsi);
}
/* TODO: Follow-on proceed */
/* TODO: CTS permission */
@@ -278,7 +283,6 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn,
/* TODO: Emergency Number List */
/* TODO: Per-MS T3312 */
- DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
return gsm48_conn_sendmsg(msg, conn, NULL);
}
@@ -415,8 +419,10 @@ int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb *msg)
(void*)&conn_from_lu,
net->vlr, conn, vlr_lu_type, tmsi, imsi,
&old_lai, &new_lai,
- is_utran || conn->network->authentication_required,
- conn->network->a5_encryption,
+ is_utran
+ || conn->network->authentication_required,
+ is_utran? VLR_CIPH_A5_3
+ : conn->network->a5_encryption,
classmark_is_r99(&conn->classmark),
is_utran,
is_utran || net->vlr->cfg.assign_tmsi);
@@ -3788,8 +3794,20 @@ static int msc_vlr_set_ciph_mode(void *msc_conn_ref,
return -EINVAL;
}
- return msc_gsm0808_tx_cipher_mode(conn, ciph, tuple->vec.kc, 8,
- retrieve_imeisv);
+ switch (conn->via_ran) {
+ case RAN_GERAN_A:
+ return msc_gsm0808_tx_cipher_mode(conn, ciph, tuple->vec.kc, 8,
+ retrieve_imeisv);
+ case RAN_UTRAN_IU:
+ return iu_tx_sec_mode_cmd(conn->iu.ue_ctx, tuple, 0, 1);
+
+ default:
+ break;
+ }
+ LOGP(DMM, LOGL_ERROR,
+ "%s: cannot start ciphering, unknown RAN type %d\n",
+ vlr_subscr_name(conn->vsub), conn->via_ran);
+ return -ENOTSUP;
}
/* VLR informs us that the subscriber data has somehow been modified */
diff --git a/openbsc/src/libvlr/vlr.c b/openbsc/src/libvlr/vlr.c
index 8cfa832..de08251 100644
--- a/openbsc/src/libvlr/vlr.c
+++ b/openbsc/src/libvlr/vlr.c
@@ -930,6 +930,9 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops)
{
struct vlr_instance *vlr = talloc_zero(ctx, struct vlr_instance);
OSMO_ASSERT(vlr);
+
+ /* Some of these are needed only on UTRAN, but in case the caller wants
+ * only GERAN, she should just provide dummy callbacks. */
OSMO_ASSERT(ops->tx_auth_req);
OSMO_ASSERT(ops->tx_auth_rej);
OSMO_ASSERT(ops->tx_id_req);
diff --git a/openbsc/src/osmo-msc/iucs_ranap.c b/openbsc/src/osmo-msc/iucs_ranap.c
index 09b8148..db6261c 100644
--- a/openbsc/src/osmo-msc/iucs_ranap.c
+++ b/openbsc/src/osmo-msc/iucs_ranap.c
@@ -55,18 +55,11 @@ static int iucs_rx_rab_assign(struct gsm_subscriber_connection *conn,
int iucs_rx_sec_mode_compl(struct gsm_subscriber_connection *conn,
RANAP_SecurityModeCompleteIEs_t *ies)
{
+ struct vlr_ciph_result vlr_res;
gsm_cbfn *cb;
OSMO_ASSERT(conn->via_ran == RAN_UTRAN_IU);
- if (!conn->sec_operation) {
- LOGP(DIUCS, LOGL_ERROR,
- "Received Security Mode Complete message, but no"
- " authentication/cipher operation in progress"
- " for subscr %s\n", vlr_subscr_name(conn->vsub));
- return -EINVAL;
- }
-
/* TODO evalute ies */
if (conn->iu.integrity_protection)
@@ -76,11 +69,8 @@ int iucs_rx_sec_mode_compl(struct gsm_subscriber_connection *conn,
conn->iu.integrity_protection = INTEGRITY_PROTECTION_IK;
- cb = conn->sec_operation->cb;
- if (cb)
- cb(GSM_HOOK_RR_SECURITY, GSM_SECURITY_SUCCEEDED, NULL,
- conn, conn->sec_operation->cb_data);
- release_security_operation(conn);
+ vlr_res.cause = VLR_CIPH_COMPL;
+ vlr_subscr_rx_ciph_res(conn->vsub, &vlr_res);
return 0;
}
diff --git a/openbsc/tests/msc_vlr/msc_vlr_test_umts_authen.c b/openbsc/tests/msc_vlr/msc_vlr_test_umts_authen.c
index 6b49dcb..a3537dd 100644
--- a/openbsc/tests/msc_vlr/msc_vlr_test_umts_authen.c
+++ b/openbsc/tests/msc_vlr/msc_vlr_test_umts_authen.c
@@ -99,10 +99,25 @@ void _test_umts_authen(enum ran_type via_ran)
VERBOSE_ASSERT(auth_request_sent, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
- btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0");
- ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
- VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+ if (via_ran == RAN_GERAN_A) {
+ btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
+ gsup_expect_tx("04010809710000000156f0");
+ ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
+ VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+ VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
+ } else {
+ /* On UTRAN */
+ btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+ cipher_mode_cmd_sent = false;
+ ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
+ VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+ VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+ btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
+ gsup_expect_tx("04010809710000000156f0");
+ ms_sends_security_mode_complete();
+ VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
+ }
btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
gsup_rx("10010809710000000156f00804032443f2",
diff --git a/openbsc/tests/msc_vlr/msc_vlr_tests.c b/openbsc/tests/msc_vlr/msc_vlr_tests.c
index feef3a0..87a5dfd 100644
--- a/openbsc/tests/msc_vlr/msc_vlr_tests.c
+++ b/openbsc/tests/msc_vlr/msc_vlr_tests.c
@@ -34,6 +34,7 @@
#include <openbsc/gsm_04_11.h>
#include <openbsc/bsc_subscriber.h>
#include <openbsc/debug.h>
+#include <openbsc/iucs_ranap.h>
#include "msc_vlr_tests.h"
@@ -550,17 +551,40 @@ static int fake_vlr_tx_ciph_mode_cmd(void *msc_conn_ref, enum vlr_ciph ciph,
* gsm0808_cipher_mode() directly. When the MSCSPLIT is ready, check
* the tx bytes in the sense of dtap_expect_tx() above. */
struct gsm_subscriber_connection *conn = msc_conn_ref;
- btw("sending Ciphering Mode Command for %s: cipher=%s kc=%s"
- " retrieve_imeisv=%d",
- vlr_subscr_name(conn->vsub),
- vlr_ciph_name(conn->network->a5_encryption),
- osmo_hexdump_nospc(conn->vsub->last_tuple->vec.kc, 8),
- retrieve_imeisv);
+ switch (conn->via_ran) {
+ case RAN_GERAN_A:
+ btw("sending Ciphering Mode Command for %s: cipher=%s kc=%s"
+ " retrieve_imeisv=%d",
+ vlr_subscr_name(conn->vsub),
+ vlr_ciph_name(conn->network->a5_encryption),
+ osmo_hexdump_nospc(conn->vsub->last_tuple->vec.kc, 8),
+ retrieve_imeisv);
+ break;
+ case RAN_UTRAN_IU:
+ btw("sending SecurityModeControk for %s",
+ vlr_subscr_name(conn->vsub));
+ break;
+ default:
+ btw("UNKNOWN RAN TYPE");
+ OSMO_ASSERT(false);
+ return -1;
+ }
cipher_mode_cmd_sent = true;
cipher_mode_cmd_sent_with_imeisv = retrieve_imeisv;
return 0;
}
+void ms_sends_security_mode_complete()
+{
+ OSMO_ASSERT(g_conn);
+ OSMO_ASSERT(g_conn->via_ran == RAN_UTRAN_IU);
+ OSMO_ASSERT(g_conn->iu.ue_ctx);
+ /* TODO mock IEs or call vlr callback directly */
+ iucs_rx_ranap_event(g_conn->network, g_conn->iu.ue_ctx,
+ IU_EVENT_SECURITY_MODE_COMPLETE,
+ NULL);
+}
+
const struct timeval fake_time_start_time = { 123, 456 };
void fake_time_start()
diff --git a/openbsc/tests/msc_vlr/msc_vlr_tests.h b/openbsc/tests/msc_vlr/msc_vlr_tests.h
index 95f210e..c164074 100644
--- a/openbsc/tests/msc_vlr/msc_vlr_tests.h
+++ b/openbsc/tests/msc_vlr/msc_vlr_tests.h
@@ -98,6 +98,7 @@ void paging_expect_imsi(const char *imsi);
void paging_expect_tmsi(uint32_t tmsi);
void ms_sends_msg(const char *hex);
+void ms_sends_security_mode_complete();
void gsup_rx(const char *rx_hex, const char *expect_tx_hex);
void send_sms(struct vlr_subscr *receiver,
struct vlr_subscr *sender,
@@ -133,7 +134,10 @@ void check_talloc(void *msgb_ctx, void *tall_bsc_ctx, int expected_blocks);
#define gsup_expect_tx(hex) do \
{ \
- OSMO_ASSERT(!gsup_tx_expected); \
+ if (gsup_tx_expected) { \
+ log("Previous expected GSUP tx was not confirmed!"); \
+ OSMO_ASSERT(!gsup_tx_expected); \
+ } \
if (!hex) \
break; \
gsup_tx_expected = hex; \