summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-03-21 22:27:15 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-03-22 19:54:09 +0100
commitdebb0e386871e64a769d7414b71bedec09d7e76a (patch)
tree4c2dcaec7f22257e2d650ceacc5759805f5853f7
parentd025a3cfbb53f690a4ebbd628cafda81c1b34bc7 (diff)
cscn: implement integrity protection
Upon authentication response, initiate integrity protection for Iu by sending a Security Mode Command (IK), with hardcoded auth tuple so far. Implement RANAP event handling to receive Security Mode Complete message, adding stubs for the other events; in new files osmo-cscn/iucs_ranap.[hc] to keep RANAP dependencies separate, and particularly out of libmsc. Upon receiving Security Mode Complete, call the security operation callback (conn->sec_operation->cb) to complete the Location Update. Introduce enum integrity_protection_state constants to indicate integrity protection, record in gsm_subscriber_conn.iu.integrity_protection. Make subscr_conn_lookup_iu() non-static and declare in iu_cs.h to be able to call from iucs_ranap.c's Security Mode Complete event. Implement dummy iu_tx_sec_mode_cmd() to allow tests to build without RANAP dependencies. In cscn_main.c, call iucs_rx_ranap_event(), to populate the struct gsm_network struct with cscn_network explicitly (don't share cscn_network across compilation scopes because it's ugly).
-rw-r--r--openbsc/include/openbsc/gsm_data.h7
-rw-r--r--openbsc/include/openbsc/iu_cs.h2
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c25
-rw-r--r--openbsc/src/libmsc/iu_cs.c6
-rw-r--r--openbsc/src/osmo-cscn/Makefile.am7
-rw-r--r--openbsc/src/osmo-cscn/cscn_main.c6
-rw-r--r--openbsc/src/osmo-cscn/iucs_ranap.c110
-rw-r--r--openbsc/src/osmo-cscn/iucs_ranap.h7
-rw-r--r--openbsc/tests/libiudummy/iudummy.c6
9 files changed, 167 insertions, 9 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index ce16c72b5..0a450d754 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -105,6 +105,12 @@ enum interface_type {
IFACE_IU = 1 /* Iu-interface for UMTS aka 3G (IuCS or IuPS) */
};
+enum integrity_protection_state {
+ INTEGRITY_PROTECTION_NONE = 0,
+ INTEGRITY_PROTECTION_IK = 1,
+ INTEGRITY_PROTECTION_IK_CK = 2,
+};
+
/* mobile subscriber data */
struct gsm_subscriber_connection {
struct llist_head entry;
@@ -151,6 +157,7 @@ struct gsm_subscriber_connection {
/* which Iu-CS connection, if any. */
struct {
struct ue_conn_ctx *ue_ctx;
+ int integrity_protection;
} iu;
#else
diff --git a/openbsc/include/openbsc/iu_cs.h b/openbsc/include/openbsc/iu_cs.h
index 60ff92d25..fb5b6972a 100644
--- a/openbsc/include/openbsc/iu_cs.h
+++ b/openbsc/include/openbsc/iu_cs.h
@@ -6,3 +6,5 @@ struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *ne
uint8_t link_id,
uint32_t conn_id);
+struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network,
+ struct ue_conn_ctx *ue);
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index a6010463b..801931f74 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -64,6 +64,7 @@
#include <osmocom/gsm/tlv.h>
#include <openbsc/msc_ifaces.h>
+#include <openbsc/iu.h>
#include <assert.h>
@@ -405,7 +406,7 @@ int gsm0408_authorize(struct gsm_subscriber_connection *conn)
" no location update operation pending\n");
return 0;
}
-
+
if (authorize_subscriber(conn->loc_operation, conn->subscr))
return gsm48_secure_channel(conn, conn->loc_operation->key_seq,
_gsm0408_authorize_sec_cb, NULL);
@@ -1156,6 +1157,28 @@ static int gsm48_rx_mm_auth_resp(struct gsm_subscriber_connection *conn, struct
return gsm0808_cipher_mode(conn, net->a5_encryption,
conn->sec_operation->atuple.kc, 8, 0);
+ if (conn->via_iface == IFACE_IU
+ && !conn->iu.integrity_protection) {
+ LOGP(DIUCS, LOGL_DEBUG,
+ "Requesting integrity protection for %s\n",
+ subscr_name(conn->subscr));
+
+ /* send Security Mode Command (IK) to start integrity
+ * protection */
+
+ /* DEV HACK: hardcoded auth tuple */
+ /* instead, employ auth_get_tuple_for_subscr() */
+ struct gsm_auth_tuple tp;
+ tp = (struct gsm_auth_tuple) {
+ .key_seq = 0,
+ .rand = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+ .sres = { 0x61, 0xb5, 0x69, 0xf5 },
+ .kc = { 0xd9, 0xd9, 0xc2, 0xed, 0x62, 0x7d, 0x68, 0x00 },
+ };
+
+ return iu_tx_sec_mode_cmd(conn->iu.ue_ctx, &tp, 0);
+ }
+
/* Only authentication requested, and we're done. */
if (!cb)
return 0;
diff --git a/openbsc/src/libmsc/iu_cs.c b/openbsc/src/libmsc/iu_cs.c
index 8d1878dc3..946d89ad5 100644
--- a/openbsc/src/libmsc/iu_cs.c
+++ b/openbsc/src/libmsc/iu_cs.c
@@ -74,8 +74,9 @@ static inline void log_subscribers(struct gsm_network *network)
/* Return an existing IuCS subscriber connection record for the given link and
* connection IDs, or return NULL if not found. */
-static struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network,
- struct ue_conn_ctx *ue)
+struct gsm_subscriber_connection *subscr_conn_lookup_iu(
+ struct gsm_network *network,
+ struct ue_conn_ctx *ue)
{
struct gsm_subscriber_connection *conn;
@@ -143,4 +144,3 @@ int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg)
return rc;
}
-
diff --git a/openbsc/src/osmo-cscn/Makefile.am b/openbsc/src/osmo-cscn/Makefile.am
index 66109ff38..545decb47 100644
--- a/openbsc/src/osmo-cscn/Makefile.am
+++ b/openbsc/src/osmo-cscn/Makefile.am
@@ -1,4 +1,5 @@
-AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) \
+ -DCOMPILING_LIBMSC=1
AM_CFLAGS=-Wall $(COVERAGE_CFLAGS) \
$(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) \
$(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) \
@@ -8,7 +9,9 @@ AM_LDFLAGS = $(COVERAGE_LDFLAGS)
bin_PROGRAMS = osmo-cscn
-osmo_cscn_SOURCES = cscn_main.c
+noinst_HEADERS = iucs_ranap.h
+
+osmo_cscn_SOURCES = cscn_main.c iucs_ranap.c
osmo_cscn_LDADD = \
$(top_builddir)/src/libiu/libiu.a \
diff --git a/openbsc/src/osmo-cscn/cscn_main.c b/openbsc/src/osmo-cscn/cscn_main.c
index 80b98731b..2b1b505a6 100644
--- a/openbsc/src/osmo-cscn/cscn_main.c
+++ b/openbsc/src/osmo-cscn/cscn_main.c
@@ -71,6 +71,8 @@
#include <openbsc/iu.h>
#include <openbsc/iu_cs.h>
+#include "iucs_ranap.h"
+
static const char * const osmocscn_copyright =
"OsmoCSCN - Osmocom Circuit-Switched Core Network implementation\r\n"
"Copyright (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>\r\n"
@@ -327,11 +329,9 @@ static int rx_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type,
{
DEBUGP(DIUCS, "got Iu-CS event %u\n", type);
- /* TODO: Handle RAB assignment response for UE */
- return 0;
+ return iucs_rx_ranap_event(cscn_network, ctx, type, data);
}
-
int main(int argc, char **argv)
{
int rc;
diff --git a/openbsc/src/osmo-cscn/iucs_ranap.c b/openbsc/src/osmo-cscn/iucs_ranap.c
new file mode 100644
index 000000000..078783f12
--- /dev/null
+++ b/openbsc/src/osmo-cscn/iucs_ranap.c
@@ -0,0 +1,110 @@
+/* Implementation of RANAP messages to/from an MSC via an Iu-CS interface.
+ * This keeps direct RANAP dependencies out of libmsc. */
+
+/* (C) 2016 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <osmocom/core/logging.h>
+
+#include <osmocom/ranap/ranap_ies_defs.h>
+
+#include <openbsc/debug.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/gsm_subscriber.h>
+#include <openbsc/iu.h>
+#include <openbsc/iu_cs.h>
+
+#include "iucs_ranap.h"
+
+/* To continue authorization after a Security Mode Complete */
+int gsm0408_authorize(struct gsm_subscriber_connection *conn);
+
+static int iucs_rx_rab_assign(struct gsm_subscriber_connection *conn,
+ RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies)
+{
+ uint8_t rab_id;
+ RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem;
+
+ rab_id = item->rAB_ID.buf[0];
+
+ LOGP(DIUCS, LOGL_NOTICE, "Received RAB assignment event for %s"
+ " rab_id=%hhd\n", subscr_name(conn->subscr), rab_id);
+ /* TODO do stuff like in sgsn_ranap_rab_ass_resp() */
+
+ return 0;
+}
+
+int iucs_rx_sec_mode_compl(struct gsm_subscriber_connection *conn,
+ RANAP_SecurityModeCompleteIEs_t *ies)
+{
+ gsm_cbfn *cb;
+
+ OSMO_ASSERT(conn->via_iface == IFACE_IU);
+
+ /* TODO evalute ies */
+
+ if (conn->iu.integrity_protection)
+ LOGP(DIUCS, LOGL_NOTICE, "Integrity Protection"
+ " was already enabled for %s\n",
+ subscr_name(conn->subscr));
+
+ conn->iu.integrity_protection = INTEGRITY_PROTECTION_IK;
+
+ cb = conn->sec_operation->cb;
+ if (!cb)
+ return 0;
+ return cb(GSM_HOOK_RR_SECURITY, GSM_SECURITY_SUCCEEDED,
+ NULL, conn, conn->sec_operation->cb_data);
+}
+
+int iucs_rx_ranap_event(struct gsm_network *network,
+ struct ue_conn_ctx *ue_ctx, int type, void *data)
+{
+ struct gsm_subscriber_connection *conn;
+
+ conn = subscr_conn_lookup_iu(network, ue_ctx);
+
+ if (!conn) {
+ LOGP(DRANAP, LOGL_NOTICE, "Cannot find subscriber for IU event %u\n", type);
+ return -1;
+ }
+
+ switch (type) {
+ case IU_EVENT_IU_RELEASE:
+ LOGP(DIUCS, LOGL_INFO, "IuCS release for %s\n",
+ subscr_name(conn->subscr));
+ msc_subscr_con_free(conn);
+ return 0;
+
+ case IU_EVENT_SECURITY_MODE_COMPLETE:
+ LOGP(DIUCS, LOGL_INFO, "IuCS security mode complete for %s\n",
+ subscr_name(conn->subscr));
+ return iucs_rx_sec_mode_compl(conn,
+ (RANAP_SecurityModeCompleteIEs_t*)data);
+ case IU_EVENT_RAB_ASSIGN:
+ return iucs_rx_rab_assign(conn,
+ (RANAP_RAB_SetupOrModifiedItemIEs_t*)data);
+ default:
+ LOGP(DIUCS, LOGL_NOTICE, "Unknown message received:"
+ " RANAP event: %i\n", type);
+ return -1;
+ }
+}
+
diff --git a/openbsc/src/osmo-cscn/iucs_ranap.h b/openbsc/src/osmo-cscn/iucs_ranap.h
new file mode 100644
index 000000000..c9fb255d3
--- /dev/null
+++ b/openbsc/src/osmo-cscn/iucs_ranap.h
@@ -0,0 +1,7 @@
+#pragma once
+
+struct ue_conn_ctx;
+
+int iucs_rx_ranap_event(struct gsm_network *network,
+ struct ue_conn_ctx *ue_ctx, int type, void *data);
+
diff --git a/openbsc/tests/libiudummy/iudummy.c b/openbsc/tests/libiudummy/iudummy.c
index 7c5129b33..770bccaa9 100644
--- a/openbsc/tests/libiudummy/iudummy.c
+++ b/openbsc/tests/libiudummy/iudummy.c
@@ -15,3 +15,9 @@ int iu_tx(struct msgb *msg, uint8_t sapi)
return 0;
}
+int iu_tx_sec_mode_cmd(struct ue_conn_ctx *uectx, struct gsm_auth_tuple *tp,
+ int send_ck)
+{
+ LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_sec_mode_cmd() dummy called, NOT transmitting Security Mode Command\n");
+ return 0;
+}